workflow:validate crashes with "Cannot read properties of undefined (reading 'const')" when the published schema has a job entry without properties.type
Maintainers usually reply within 3 days
@douglowder is already working on this.
Since Sep 30, 2026.
- #4505 by @douglowder — closed without merging
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- cli
Research direction
Start in build/commandUtils/workflow/validation.js at jobTypesFromWorkflowSchema and its call from validateWorkflowJobTypes. Reproduce with eas workflow:validate .eas/workflows/build-preview.yml --non-interactive, or use EXPO_TESTING_WORKFLOW_SCHEMA_PATH with the schema containing the catch-all job entry. Done means the validator no longer throws and validates the unchanged workflow successfully.
Written by the indexing model from the issue text.
Description
Summary
eas workflow:validate fails for every workflow file with:
- Validating the workflow YAML file…
✖ Workflow configuration YAML is not valid.
Error: Cannot read properties of undefined (reading 'const')
The failure happens before any workflow is validated, so it is not caused by the workflow content. It reproduces on a workflow that a previous CLI release reported as valid.
Cause
eas workflow:validate fetches the published workflow schema from GET /v2/workflows/schema and then builds its job-type allowlist in build/commandUtils/workflow/validation.js:
function jobTypesFromWorkflowSchema(workflowJsonSchema) {
return workflowJsonSchema?.properties?.jobs?.additionalProperties?.anyOf.map(
(props) => props.properties.type.const,
);
}
validateWorkflowJobTypes calls this before validateWorkflowStructure, so a TypeError here aborts validation entirely.
The published schema now also contains a catch-all job entry that has no properties.type (its shape is name/if/… plus additionalProperties, used for job types outside the named set). Reading props.properties.type.const on that entry throws the observed TypeError.
Entries 0-17 of anyOf all carry properties.type.const (build, custom, deploy, fingerprint, get-build, maestro-cloud, maestro, require-approval, apple-device-registration-request, submit, testflight, update, slack, doc, repack, github-comment, branch-delete, update-rollout); the additional entry does not.
Reproduction
Any project with a workflow file:
eas workflow:validate .eas/workflows/build-preview.yml --non-interactive
Checked versions: 22.6.0, 23.0.0, 24.0.0, 24.4.0, 24.8.0 (latest) — all contain the same expression and all fail.
Workaround
Point the validator at a copy of the schema without the catch-all entry, using the existing hook in fetchWorkflowSchemaAsync:
EXPO_TESTING_WORKFLOW_SCHEMA_PATH=/path/to/schema-without-catch-all.json \
eas workflow:validate .eas/workflows/build-preview.yml --non-interactive
With that entry removed the same CLI reports the unmodified workflow as valid, so the workflow content itself is fine.
Suggested fix
Collect job types defensively, ignoring entries that do not declare one:
return (workflowJsonSchema?.properties?.jobs?.additionalProperties?.anyOf ?? [])
.map((props) => props?.properties?.type?.const)
.filter((type) => typeof type === 'string');
Ideally the catch-all entry would also be distinguishable without relying on its position in anyOf.
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 254
- Avg merge
- 4d 41m
- Merged PRs (30d)
- 113
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from expo/eas-cli
-
ASC API key auth fails with Apple 401 because @expo/apple-utils signs JWTs with exactly the 1200 s maximum lifetimePossibly taken @ceydaakin claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 3 days
-
metadata:push: `apple.info.restrictedWords` flags "beta" inside other words (e.g. Danish "Betal")Possibly taken @DYNOSuprovo claimed this 13 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 3 days
-
needs review
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 3 days
-
`--no-auto-testflight-setup` is ignored when the submit profile has no `ascAppId`: `Team (Expo)` is still created and all Admins enrolled (opt-out lost in 22.0.0)Possibly taken @tahakocal claimed this 29 days ago. Openstale
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
expo/eas-cli#4397 · 1 comment ·
Maintainers usually reply within 3 days
-
Handle missing node_modules betterPossibly taken @LizunovSergey claimed this 41 days ago. Openneeds review
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 3 days
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
callstackincubator/simlock#639 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
aws/agentcore-cli#2606 ·
Maintainers usually reply within 1 day
-
ai-driven-qa bug Cosmetic
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 1 day
-
ai-driven-qa bug claude Minor
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
linagora/twake-mail-admin#301 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day