argoproj/argo-workflows · error
unable to resolve references: %w
Error message
unable to resolve references: %w
What it means
When resolving an output artifact reference (e.g. from another step's artifacts) during expandStepGroup's parallel resolution, scope.resolveArtifact failed. If the artifact is not declared optional, the whole reference resolution fails with this wrapped error.
Source
Thrown at workflow/controller/steps.go:536
return argoerrors.InternalWrapError(err)
}
// Restore Hooks
newStep.Hooks = originalHooks
artifacts := wfv1.Artifacts{}
// Step 2: replace all artifact references
for _, art := range newStep.Arguments.Artifacts {
if art.From == "" && art.FromExpression == "" {
artifacts = append(artifacts, art)
continue
}
resolvedArt, err := scope.resolveArtifact(ctx, &art)
if err != nil {
if art.Optional {
continue
}
return fmt.Errorf("unable to resolve references: %w", err)
}
if art.Optional && !resolvedArt.HasLocationOrKey() {
continue
}
resolvedArt.Name = art.Name
artifacts = append(artifacts, *resolvedArt)
}
newStep.Arguments.Artifacts = artifacts
newStepGroup[i] = newStep
return nil
}
// When resolveStepReferences we can use a channel parallelStepNum to control the number of concurrencies
parallelStepNum := make(chan string, 500)
errCh := make(chan error, len(stepGroup)) // contains the error during resolveStepReferences
var wg sync.WaitGroup
for i, step := range stepGroup {
parallelStepNum <- step.NameView on GitHub (pinned to 35bff19146)
Solutions
- Mark the consuming artifact as optional: true if the producer may be skipped
- Fix the upstream step so it actually produces the artifact
- Verify the artifact reference names and expressions are correct
Example fix
// before
inputs:
artifacts:
- name: out
from: '{{steps.build.outputs.artifacts.bin}}'
// after
inputs:
artifacts:
- name: out
from: '{{steps.build.outputs.artifacts.bin}}'
optional: true Defensive patterns
Strategy: validation
Validate before calling
// in template definition, declare optional artifacts whose producers may be skipped // inputs.artifacts[].optional: true
Prevention
- Mark consumer artifacts optional when producers can be skipped/failed
- Verify upstream steps emit the artifacts they promise
- Gate downstream steps on upstream status with when
When it happens
Trigger: A step's inputs reference an artifact (e.g. {{steps.X.outputs.artifacts.Y}} or artifacts.from expressions) whose producer step didn't produce it, was skipped, or failed — resolveArtifact returns an error and art.Optional is false.
Common situations: Downstream step consumes an artifact from a step that was skipped via when/continueOn; upstream step failed to generate the artifact; typo in artifact name/path.
Related errors
- failed to re-enter working directory %q after staging input
- failed to stat input artifact %q at %s: %w
- failed to create parent directory for artifact %q at %s: %w
- failed to stat artifact path %q at %s: %w
- failed to resolve parent of artifact path %q at %s: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/65786f541c938c7e.
Report an issue: GitHub.