argoproj/argo-workflows · error
dependency %q exited with non-zero code: %d
Error message
dependency %q exited with non-zero code: %d
What it means
In a container-set (emissary) workflow, a container that declares dependencies waits for each dependency's exitcode file and fails immediately if that dependency exited non-zero. This error propagates the dependency's exit code so the workflow step is marked Failed with a clear cause.
Source
Thrown at cmd/argoexec/commands/emissary.go:203
for _, x := range template.ContainerSet.GetGraph() {
if x.Name == containerName {
for _, y := range x.Dependencies {
logger.WithField("dependency", y).Info(ctx, "waiting for dependency")
depDir := filepath.Clean(varRunArgo + "/ctr/" + y)
// The dependency container will MkdirAll this too, but may not have
// started yet; pre-create it so we can install an inotify watch on it.
if err = os.MkdirAll(depDir, 0o777); err != nil {
return fmt.Errorf("failed to create dependency dir: %w", err)
}
depExitPath := filepath.Join(depDir, "exitcode")
code, waitErr := waitForDependencyExitCode(ctx, depExitPath, signals)
if waitErr != nil {
return waitErr
}
exitCode = code
if exitCode != 0 {
return fmt.Errorf("dependency %q exited with non-zero code: %d", y, exitCode)
}
}
}
}
name, err = exec.LookPath(name)
if err != nil {
return fmt.Errorf("failed to find name in PATH: %w", err)
}
if os.Getenv("ARGO_DEBUG_PAUSE_BEFORE") == "true" {
// User can create the file: /ctr/NAME_OF_THE_CONTAINER/before
// in order to break out of the wait and release the container from
// the debugging state.
if waitErr := file.WaitForCreate(ctx, varRunArgo+"/ctr/"+containerName+"/before"); waitErr != nil {
return fmt.Errorf("failed waiting for debug-pause-before marker: %w", waitErr)
}
}View on GitHub (pinned to 35bff19146)
Solutions
- Look at the logs of the dependency container named in the error to find its actual failure
- Fix the dependency's command/image so it exits 0
- If the dependency may legitimately fail, remove it from Dependencies or make it tolerant (retry strategy / ignore exit code)
- Use `argo logs <pod> -c <dependency-container>` and the node's exit code in the UI to confirm
Example fix
// before containers: - name: main dependencies: [setup] - name: setup image: busybox command: ["sh", "-c", "exit 1"] // after - name: setup image: busybox command: ["sh", "-c", "setup.sh || true"]
Defensive patterns
Strategy: retry
Validate before calling
// before submit, ensure dependency commands exit 0 in CI smoke tests // e.g. docker run --rm <image> <dependency command> && echo ok
Try / catch
try { await runStep() } catch (e) { const m = e.message.match(/dependency "(.+?)" exited with non-zero code: (\d+)/); if (m) { const logs = await getPodLogs(pod, m[1]); throw new Error(`dep ${m[1]} failed (${m[2]}): ${logs}`) } throw e } Prevention
- Add retryStrategy to flaky dependency containers
- Lint dependency container commands with a smoke run in CI
- Check `argo logs --prefix -c <dep>` first when a container-set step fails
- Avoid brittle setup scripts in dependency containers
When it happens
Trigger: A dependency container listed in x.Dependencies terminated with exit code != 0; waitForDependencyExitCode returned that code and runEmissary aborts before starting its own command.
Common situations: The dependency container crashed (application error, bad image, OOMKilled with non-zero exit), a sidecar/init-like container in a container set failed its setup, or the dependency's script had a bug.
Related errors
- failed to create dependency dir: %w
- watching supervisor status: %w
- supervisor presumed dead: status marker never appeared withi
- stat supervisor status: %w
- supervisor reported pre-main failure: %s
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/82beef1a8beda3c8.
Report an issue: GitHub.