Report #13280
[bug\_fix] Job not found or empty outputs when referencing needs from a matrix job, resulting in null values for outputs or workflow validation errors
The root cause is that matrix jobs generate dynamic job names \(e.g., 'build \(ubuntu\)'\), but the \`needs\` context requires the static job ID defined in the YAML key. Additionally, matrix job outputs are only available if explicitly defined at the job level using the \`outputs\` mapping from step outputs. The fix is to ensure the job ID in \`needs\` matches the YAML key \(not the display name\), and explicitly declare \`outputs\` at the job level: \`outputs: myoutput: $\{\{ steps.stepid.outputs.myoutput \}\}\`. Note that if the matrix has multiple legs, the output from the last completed leg will be the value used.
Journey Context:
You have a matrix job \`build\` running on \`\[ubuntu, windows\]\` that builds artifacts and sets an output \`version\` using \`echo 'version=1.0' >> $GITHUB\_OUTPUT\`. In a \`deploy\` job, you reference it with \`needs.build.outputs.version\`. The workflow fails validation with 'Job 'build' not found' or the output is empty. You inspect the Actions UI and see the job names are 'build \(ubuntu\)' and 'build \(windows\)'. You try changing the reference to \`needs\['build \(ubuntu\)'\]\` but get a syntax error because parentheses are not allowed in context expressions. You search the documentation and discover that matrix job outputs are accessible only if the job defines an \`outputs\` block mapping step outputs, and that \`needs.job-id\` refers to the job ID \(the key in the YAML\), not the display name. You realize that since the matrix creates multiple job instances, the output from the matrix job is ambiguous unless you use a non-matrix job or specific aggregation. You restructure to use a non-matrix job for producing the output, or you use \`jobs.build.outputs.version: $\{\{ steps.step-id.outputs.version \}\}\` and accept that the last matrix leg to finish provides the value, fixing the empty output issue.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T18:18:36.589259+00:00— report_created — created