argoproj/argo-workflows · error
failed to re-enter working directory %q after staging input
Error message
failed to re-enter working directory %q after staging input artifacts (an input artifact staged at the workingDir path must be a directory): %w
What it means
After symlinking input artifacts, argoexec chdirs back to the directory it saved at the start. This error means that restore failed, and the message explains the usual root cause: an input artifact was staged at the template's workingDir path but was a file/symlink rather than a directory, so the original path no longer leads back to a directory.
Source
Thrown at cmd/argoexec/commands/emissary.go:359
// into place and re-enters the working directory afterwards, stepping off it
// for the duration: linking replaces the cwd when an artifact's path is the
// container's workingDir, Windows refuses to delete a directory in use as a
// working directory, and a child forked with the deleted directory as cwd
// would see getcwd() fail and relative paths resolve to nothing. The final
// chdir follows the symlink to whatever now sits at the path.
func stageInputArtifactsAt(ctx context.Context, baseDir string, tmpl *wfv1.Template) error {
origWd, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed to read working directory before staging input artifacts: %w", err)
}
if err := os.Chdir(varRunArgo); err != nil {
return fmt.Errorf("failed to leave working directory before staging input artifacts: %w", err)
}
if err := linkInputArtifactsAt(ctx, baseDir, tmpl); err != nil {
return err
}
if err := os.Chdir(origWd); err != nil {
return fmt.Errorf("failed to re-enter working directory %q after staging input artifacts (an input artifact staged at the workingDir path must be a directory): %w", origWd, err)
}
return nil
}
// linkInputArtifactsAt creates a symlink at each input artifact's path
// pointing to the file that supervisor wrote under /argo/inputs/artifacts/
// <name>. This replaces the legacy SubPath bind-mount-per-artifact scheme,
// which can't be used in init-less mode because kubelet pre-creates SubPath
// entries as empty directories before supervisor can write the real file.
//
// Behavior notes for workflow authors: in init-less mode art.Path is a
// symlink rather than a regular file. `cat`, `open()`, `tar`, `cp`,
// redirection, etc. all follow symlinks transparently and see identical
// content. Code that calls `lstat`/`readlink` on art.Path will observe a
// symlink rather than a regular file. `rm art.Path` removes the symlink
// only; the underlying artifact stays in the shared emptyDir.
//
// Overlapping user volumes are handled by the executor on the write sideView on GitHub (pinned to 35bff19146)
Solutions
- Change the input artifact's path so it is a subdirectory of workingDir, not workingDir itself, when the artifact is a file.
- Use a directory-type artifact if the working directory must be the artifact root.
- Access a file artifact by explicit absolute path in the script instead of relying on cwd.
- Fix the workingDir/artifact.path overlap in the template spec and re-run the workflow.
Example fix
// before
workingDir: /workspace
inputs.artifacts: [{name: code, path: /workspace, ...}] # file artifact replaces cwd
// after
inputs.artifacts: [{name: code, path: /workspace/code, ...}] Defensive patterns
Strategy: validation
Validate before calling
// Reject templates where a file artifact path collides with workingDir:
const bad = tmpl.inputs.artifacts.some(a => a.path === tmpl.workingDir && a.artifactPathIsFile)
if (bad) throw new Error('file artifact path must not equal workingDir') Try / catch
try {
await stageArtifacts(tmpl)
} catch (e) {
if (String(e).includes('failed to re-enter working directory')) {
// fix artifact.path/workingDir overlap in the template spec
}
} Prevention
- Keep artifact paths strictly under workingDir, never equal to it, for file artifacts.
- Lint templates for workingDir/artifact.path collisions before submit.
- Use directory artifacts if you intend the artifact root to be the working directory.
When it happens
Trigger: os.Chdir(origWd) fails after linkInputArtifactsAt ran — typically because the artifact path equals the working directory and the staged entry is a file (symlink) instead of a directory, or the directory was removed during staging.
Common situations: Template with workingDir set to the same path as a file-type input artifact; artifact path accidentally nested under the workingDir causing the dir to be replaced; typos where artifact.path == workingDir.
Related errors
- failed to read working directory before staging input artifa
- 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/bc47af72b2100095.
Report an issue: GitHub.