GitHub Actions job that needs a matrix waits for all combinations in CI
When a job declares needs: <matrix-job>, it waits for every leg of that matrix to complete and, by default, runs only if all legs succeeded. A single failed or cancelled leg makes the downstream job skip, which is not always what you want.
What this error means
A deploy or aggregate job that needs a matrix job does not run, or waits far longer than expected, because one matrix leg failed or is still running.
deploy:
needs: build # build is a matrix; deploy waits for ALL legs and skips if any failsCommon causes
needs waits for the entire matrix
A dependency on a matrix job depends on all its legs collectively, so the downstream job blocks until the slowest leg finishes.
Default success gating skips on any failure
Without an explicit condition, the downstream job requires every leg to succeed, so one failure skips it.
How to fix it
Control the downstream condition explicitly
- Decide whether the downstream job should run on partial success.
- Use
if: always()orif: !cancelled()with a status check if needed. - Read leg results via the matrix job's outputs where required.
deploy:
needs: build
if: ${{ !cancelled() && needs.build.result == 'success' }}
runs-on: ubuntu-latestAggregate matrix outputs in a gate job
Collect per-leg outputs into a small aggregate job so downstream jobs depend on a single clear signal.
How to prevent it
- Expect needs on a matrix to wait for every leg.
- Set an explicit if to control partial-success behavior.
- Aggregate matrix results into one gate job for clarity.