GitHub Actions "The expression is too long (max 21000 characters)"
Every individual GitHub Actions expression is parsed into an AST and is capped at 21000 characters. A giant inlined fromJSON blob, a long concatenated string, or a deeply nested toJSON usually trips it.
What this error means
The workflow fails at parse time on a single key that contains one large \${{ }} expression, most often a matrix built from an inlined JSON literal or a long interpolated run command.
Invalid workflow file: .github/workflows/ci.yml#L22
The expression is too long. Max allowed length: 21000Common causes
Huge inline JSON passed to fromJSON
A matrix or value built from a large JSON literal embedded directly in the YAML inflates a single expression past the ceiling.
Long concatenated/interpolated string
Building a big command or payload with many \${{ }} concatenations inside one expression hits the limit.
How to fix it
Move the large value out of the expression
- Generate the JSON in a prior step and pass it through GITHUB_OUTPUT, then reference the output once.
- Split a long interpolation into multiple steps or multiple smaller expressions.
- For matrices, produce the array in a setup job and consume it with fromJSON of a single short output.
jobs:
setup:
runs-on: ubuntu-latest
outputs:
items: ${{ steps.gen.outputs.items }}
steps:
- id: gen
run: echo "items=$(cat matrix.json)" >> "${GITHUB_OUTPUT}"
build:
needs: setup
strategy:
matrix:
item: ${{ fromJSON(needs.setup.outputs.items) }}How to prevent it
- Keep generated data in step outputs or files, not inlined into one expression.
- Reference outputs by name instead of re-building large strings inline.