Matrix job skipped - empty matrix combination
Matrix strategy produces fewer jobs than expected
Focused incident mode — strips away everything but this runbook.
Symptoms
- Matrix strategy produces fewer jobs than expected
- Some OS/language combinations never run in the matrix
- Workflow completes green but certain matrix legs are absent from the run
GitHub Actions resolves exclude before include. An exclude that removes a key combination will also remove that combination from explicit includes.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Matrix include/exclude block
cat .github/workflows/<file>.yml | grep -A30 'strategy:'Actual matrix jobs in the run
gh run view <RUN_ID> --repo <OWNER/REPO> --json jobs --jq '.jobs[] | .name'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- exclude: - os: windows-latest matches every combination, removing all windows jobs
- Only ubuntu-latest jobs appear in the run
Confirm before fixing
cat .github/workflows/<file>.yml | grep -A20 'exclude:'Read the exclude block
Fix
cat .github/workflows/<file>.yml | sed '/exclude:/,/^[^ ]/{/windows-latest/d;}'Remove or correct the overly broad exclude rule
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
gh run view <RUN_ID> --repo <OWNER/REPO> --json jobs --jq '.jobs[] | .name'List which matrix jobs actually ran
cat .github/workflows/<file>.yml | grep -A30 'strategy:'Read the matrix, include, and exclude definitions
cat .github/workflows/<file>.yml | grep -E 'if:' | head -10Check for conditional filters on the matrix job
Prevention
- After defining matrix include/exclude, manually verify the full cross-product with a dry-run.
- Use github.event.action == 'schedule' guards instead of complex exclude blocks.
- Add a post-job step that reports which matrix legs ran vs expected.
- Keep matrix dimensions small; split into separate workflows if the cross-product is large.
Related runbooks
Same stack, same failure family — worth a skim.
Push to main does not trigger any workflow run
Workflow run fails immediately with 'Invalid workflow file'
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.