mediumIntermediateSymptom-first#matrix#strategy#conditional#jobs

Matrix job skipped - empty matrix combination

Matrix strategy produces fewer jobs than expected

Likely source:configurationdeployment

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

Read the exclude block

Fix

cat .github/workflows/<file>.yml | sed '/exclude:/,/^[^ ]/{/windows-latest/d;}'
CHANGE

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.

1
gh run view <RUN_ID> --repo <OWNER/REPO> --json jobs --jq '.jobs[] | .name'
READ

List which matrix jobs actually ran

2
cat .github/workflows/<file>.yml | grep -A30 'strategy:'
READ

Read the matrix, include, and exclude definitions

3
cat .github/workflows/<file>.yml | grep -E 'if:' | head -10
READ

Check 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.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.