Skip to content
Latchkey

GitHub Actions needs.<job>.outputs Undefined Across Jobs

A downstream job reads needs.<job>.outputs.<name> and gets nothing because the upstream job did not expose that value as a job output, or the job is not listed in needs.

What this error means

A consumer job sees an empty value from needs.<job>.outputs even though the producing step set a step output. The data does not cross the job boundary.

.github/workflows/ci.yml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - id: v
        run: echo "ver=1.0.0" >> "$GITHUB_OUTPUT"
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - run: echo "${{ needs.build.outputs.ver }}"   # empty: build never mapped it

Common causes

Job output not mapped from the step output

Step outputs are local to a job. To cross jobs, the producing job must declare jobs.<id>.outputs and map each one to a steps.<id>.outputs reference.

Consumer missing needs on the producer

The needs context only contains jobs the current job depends on. Without needs: build, needs.build is unavailable.

How to fix it

Map step outputs to job outputs

.github/workflows/ci.yml
jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      ver: ${{ steps.v.outputs.ver }}
    steps:
      - id: v
        run: echo "ver=1.0.0" >> "$GITHUB_OUTPUT"
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - run: echo "${{ needs.build.outputs.ver }}"

Verify the dependency chain

  1. List every producer in the consumer job needs.
  2. Match the job output name in the producer to the needs reference.
  3. Remember a skipped or failed producer leaves its outputs empty.

How to prevent it

  • Always declare jobs.<id>.outputs when another job consumes a value.
  • Keep output names identical between producer and consumer.
  • Guard consumers with if: needs.<job>.result == 'success' where appropriate.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →