Report #92638
[bug\_fix] Matrix job outputs empty or workflow validation fails when referencing matrix job outputs via needs
Matrix jobs cannot expose outputs directly because they generate dynamic job IDs. Instead, have each matrix job upload its results as artifacts using \`actions/upload-artifact\` with unique names \(e.g., \`result-$\{\{ matrix.os \}\}\`\), then add a final aggregation job that depends on the matrix job and downloads all artifacts using \`actions/download-artifact\` with a pattern \(e.g., \`result-\*\`\).
Journey Context:
A developer creates a matrix job named \`test\` that runs across \`ubuntu\`, \`windows\`, and \`macos\`. Each instance produces a coverage report, and the developer attempts to aggregate these in a final \`upload-coverage\` job by referencing \`needs.test.outputs.coverage\`. The workflow fails validation with an error indicating that \`test\` is not a valid job ID for outputs, or the output value is empty. The developer checks the documentation and realizes that matrix jobs dynamically create job IDs like \`test \(ubuntu\)\`, \`test \(windows\)\`, etc., making it impossible to statically reference their outputs in \`needs\`. They attempt to use the matrix context in the dependent job, but this fails because the context is not available across jobs. The debugging leads them to understand that GitHub Actions does not support passing outputs from matrix jobs directly due to the dynamic nature of the job names. The solution is to use artifact passing: each matrix instance uploads its coverage file with a unique name including the matrix variable \(e.g., \`coverage-$\{\{ matrix.os \}\}\`\), and the final job uses \`actions/download-artifact\` with \`pattern: coverage-\*\` and \`merge-multiple: true\` to collect all results before uploading to the coverage service.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T14:04:54.051726+00:00— report_created — created