GitHub Actions · beginner
GitHub Actions artifact not found: trace the producer-consumer run boundary
A GitHub Actions artifact not found error almost always signals a boundary mismatch between the producing run and the consuming run or job. The artifact, the run id, or the reference used to fetch it is anchored to a different execution context than the consumer expects. Treat this as a producer/consumer boundary problem before changing upload or download steps.
The symptoms
- •actions/download-artifact step fails with "Unable to find an artifact with the name '...'" or "No artifact was found for the name: ..."
- •actions/upload-artifact succeeds locally but the next job reports the artifact is missing from the workflow run
- •Download returns artifacts but the contents are empty or refer to a previous run id, not the current one
- •Upload step reports a successful upload yet the consumer job cannot see any artifact at all in the run summary
- •Error references a different run id or workflow than the one that just produced the upload
Likely causes
- •Producer job was skipped, cancelled, or failed before the upload-artifact step executed, so nothing was registered for the run
- •Consumer job runs in a different workflow_run that is not the same execution, so the artifact name and run id do not match
- •needs context is missing or misnamed, so the consumer does not wait for the producer and races against upload completion
- •Conditional logic (if:) resolved to false on the upload step, silently skipping the upload while the consumer assumes it ran
- •An earlier job with the same name in the workflow re-uploaded an artifact and overwrote what the consumer expected
- •artifact name drifted between producer and consumer due to a path expression or matrix expansion that evaluates differently per runner
First ten minutes
- 01Open the failing workflow run summary and read the run id from the URL or top-of-page header; note it as the consumer's run id
- 02Open the Artifacts section at the bottom of the run summary and confirm whether any artifact is listed for the consumer's run id
- 03Inspect the producer job's status icon; if it is skipped, cancelled, or failed, the upload step never executed and no artifact exists for this run
- 04Compare the workflow YAML referenced by the producer step against the consumer's needs: declaration to confirm the producer job name matches exactly
- 05Read the failing download-artifact step's log and capture the artifact name, the run id it is resolving against, and the workflow file path it reports
- 06Decide the boundary: same-run cross-job vs cross-run cross-workflow, since the resolution rule differs between the two
Evidence to collect
- •Run id of the consumer run, taken from the GitHub Actions URL or run summary header
- •Producer job name as declared in the workflow YAML and as referenced in the consumer's needs: block
- •Artifact name string exactly as passed to both actions/upload-artifact and actions/download-artifact steps, including any expression interpolation result
- •Upload step status (success, skipped, failed) and the resolved value of any if: condition guarding it
- •Workflow file path and ref (branch or tag) the consumer run was triggered from, compared to the producer run's ref
- •Run-summary Artifacts list for the consumer's run id, showing whether the artifact is present, absent, or attached to a different run
Where to look
- •At the workflow run summary page's Artifacts section, which is the authoritative listing of artifacts owned by that specific run id
- •At the producer job's step list, specifically the upload-artifact step log lines showing the resolved name and the upload target run
- •At the consumer job's needs: block in the workflow YAML, since needs gates both job ordering and artifact resolution across jobs in the same run
- •At the d.yaml or workflow file referenced by the failing download-artifact error, to confirm the consumer is looking at the expected workflow definition
- •At the run's metadata fields (event, ref, run attempt), which determine how run ids and artifact scoping interact across retries and re-runs
Diagnostic steps
- 01Confirm the consumer's run id equals the producer's run id; if they differ, you are looking at a cross-run reference and must treat the producer as a separate execution
- 02Verify the producer job's needs relationship is satisfied (status success or specified condition) before the consumer is allowed to run
- 03Compare the artifact name string byte-for-byte between upload and download steps, including dynamic segments resolved at runtime
- 04Inspect the upload step's resolved if: condition in the workflow log to confirm the upload was not skipped at runtime
- 05Check whether the producing workflow uses a matrix or reusable workflow that may emit multiple artifacts under the same name on parallel runners
- 06For cross-workflow consumers, confirm the download step targets the correct workflow name and run id, not just the artifact name
- 07Rule out run-attempt drift: artifacts from a previous attempt are not automatically visible to a new attempt of the same job
Common mistakes
- •Assuming the artifact exists because the upload step reported success, without checking the run-summary Artifacts list for the actual run id
- •Using the same artifact name across two unrelated workflows and expecting the consumer to find the latest upload globally rather than the specific run it references
- •Adding a new needs: entry but forgetting that GitHub Actions resolves artifacts only along declared needs dependencies, not by job name proximity
- •Interpolating the artifact name from a variable that expands differently on the upload runner versus the download runner, so the names silently diverge
- •Re-running only the consumer job instead of the full workflow, which can cause the download step to resolve against an earlier run attempt's artifact scope
Safe fixes
- •If the producer was skipped or failed, fix the upstream condition so the upload step is actually reachable before changing the consumer
- •If the consumer run id differs from the producer run id, switch the download step to a cross-run reference that explicitly names the producer workflow and run id
- •If needs: is missing or misnamed, add the producer job to the consumer's needs: block so artifact resolution is scoped to the in-run dependency
- •If the artifact name is dynamic, centralize the name in a workflow-level output or env and reference it from both producer and consumer steps to avoid drift
- •If matrix expansion causes name collisions, append a matrix identifier to the artifact name on the producer so each leg produces a uniquely named artifact
Prove the fix
- 01Re-run the workflow and confirm the consumer's run summary Artifacts list shows the expected artifact name under the same run id as the producer
- 02Grep the consumer job's download-artifact log for the resolved run id and confirm it matches the producer's run id shown in the run summary header
- 03Verify the consumer's needs: block lists the producer job and that the producer job's status is success in the run graph before the consumer starts
- 04Inspect the uploaded artifact's contents in the run summary and confirm the files inside match what the consumer step expected to read
- 05Repeat the re-run at least once and confirm the artifact still resolves correctly, ruling out a one-time match from a stale run attempt
Prevention and next steps
- •Keep artifact names static and defined once at the workflow level, referenced from both producer and consumer steps, so name drift cannot occur between runs
- •Always declare the producer job in the consumer's needs: block, even when the consumer only depends on the artifact and not the producer's outputs
- •Add an explicit assertion step early in the consumer that fails fast if the expected artifact name is missing, rather than relying on the download step's generic error
- •Avoid conditionally skipping the upload step with the same name pattern used elsewhere; prefer distinct names per producer to keep consumption deterministic