{"record":{"id":"49d952dd8f570235","repo":"argoproj/argo-workflows","slug":"refusing-to-stage-input-artifact-q-at-s-it-reso","errorCode":null,"errorMessage":"refusing to stage input artifact %q at %s: it resolves to %s inside volume mount %q (%s), and clearing it would destroy the mounted volume; change the artifact path or volume mount so they do not overlap","messagePattern":"refusing to stage input artifact %q at (.+?): it resolves to (.+?) inside volume mount %q \\((.+?)\\), and clearing it would destroy the mounted volume; change the artifact path or volume mount so they do not overlap","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/argoexec/commands/emissary.go","lineNumber":428,"sourceCode":"\t\t\t}\n\t\t} else {\n\t\t\t// Something is already at art.Path. Replacing it (os.RemoveAll then\n\t\t\t// symlink) reproduces the legacy SubPath mount's shadowing — but only\n\t\t\t// when it is safe. RemoveAll resolves symlinks in the parent chain, so\n\t\t\t// resolve the parent to find where the delete would actually land\n\t\t\t// (resolve the parent, not the final element, so an image symlink *at*\n\t\t\t// art.Path is just unlinked rather than followed). If that resolved\n\t\t\t// path overlaps a user-declared volume, clearing it would recurse into\n\t\t\t// and destroy a live PVC/hostPath/emptyDir, so refuse. Benign system\n\t\t\t// mounts (tmpfs /run, the overlay rootfs) are not declared user volumes\n\t\t\t// and so remain safe to shadow.\n\t\t\trealParent, evalErr := filepath.EvalSymlinks(filepath.Dir(dst))\n\t\t\tif evalErr != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to resolve parent of artifact path %q at %s: %w\", art.Name, dst, evalErr)\n\t\t\t}\n\t\t\tresolved := filepath.Join(realParent, filepath.Base(dst))\n\t\t\tif mnt := common.FindOverlappingVolume(tmpl, resolved); mnt != nil {\n\t\t\t\treturn fmt.Errorf(\"refusing to stage input artifact %q at %s: it resolves to %s inside volume mount %q (%s), and clearing it would destroy the mounted volume; change the artifact path or volume mount so they do not overlap\", art.Name, dst, resolved, mnt.Name, mnt.MountPath)\n\t\t\t}\n\t\t\tif mnt := common.FindVolumeMountNestedUnderPath(tmpl, resolved); mnt != nil {\n\t\t\t\treturn fmt.Errorf(\"refusing to stage input artifact %q at %s: it resolves to %s which contains volume mount %q (%s), and clearing it would destroy the mounted volume; change the artifact path or volume mount so they do not overlap\", art.Name, dst, resolved, mnt.Name, mnt.MountPath)\n\t\t\t}\n\t\t\tif rmErr := os.RemoveAll(dst); rmErr != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to clear existing path for artifact %q at %s: %w\", art.Name, dst, rmErr)\n\t\t\t}\n\t\t}\n\t\tif err := os.Symlink(src, dst); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to symlink input artifact %q (%s -> %s): %w\", art.Name, dst, src, err)\n\t\t}\n\t\tlogger.WithFields(logging.Fields{\"name\": art.Name, \"src\": src, \"dst\": dst}).Debug(ctx, \"linked input artifact\")\n\t}\n\treturn nil\n}\n\n// waitForSupervisorReady blocks until the supervisor's status marker reports a\n// terminal outcome (READY/FAILED), or until the supervisor is presumed dead.","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/cmd/argoexec/commands/emissary.go#L410-L446","documentation":"When staging an input artifact that must overwrite an existing file, argoexec resolves the real filesystem location of art.Path and refuses if it lands inside a user-declared volume mount. Clearing the path there (os.RemoveAll) would destroy the contents of a live PVC/hostPath/emptyDir, so the executor fails fast instead of deleting user data.","triggerScenarios":"An input artifact's `path` resolves (after symlink evaluation of the parent) inside a volumeMount declared on the template, AND something already exists at that path so an overwrite would be required.","commonSituations":"Pointing an artifact at a path under an output-artifact volume mount (e.g. /mnt/out shared between input and output artifacts mounted via PVC); reusing the same path for an input artifact and a mounted config; mounting a volume at / and putting the artifact path under it.","solutions":["Change the input artifact's `path` to a location outside any declared volumeMount (e.g. /tmp/cfg)","If you need the artifact in the volume, mount the volume at a subdirectory and place the artifact path outside it, or stage the artifact to a temp path and copy it in a script step","Split into two mounts: one small emptyDir for the input artifact, one for the volume that must stay intact","Check `argo get <wf>` / executor logs for the resolved path in the message and adjust either path or volumeMount so they do not overlap"],"exampleFix":"# before\ncontainers:\n- volumeMounts:\n  - name: work\n    mountPath: /mnt/work\ninputs:\n  artifacts:\n  - name: data\n    path: /mnt/work/data      # overwrite would clear the mounted volume\n# after\ninputs:\n  artifacts:\n  - name: data\n    path: /tmp/inputs/data\nscript:\n  command: [sh]\n  source: cp /tmp/inputs/data /mnt/work/data","handlingStrategy":"validation","validationCode":"// Before submit, ensure no input artifact path falls inside a template volumeMount:\nconst overlaps = (artPath, mounts) =>\n  mounts.some(m => artPath === m.mountPath || artPath.startsWith(m.mountPath + '/'));\nif (overlaps(art.path, template.volumeMounts || []))\n  throw new Error(`artifact path ${art.path} overlaps a volumeMount; move it outside`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never point input artifact paths at volumeMount directories that hold other data","Use separate mounts (or a copy step) to combine input artifacts with volume data","Keep artifact destinations under a dedicated prefix like /tmp/argo-inputs","Read the resolved path in the error message — it tells you exactly which mountPath conflicts"],"tags":["kubernetes","argo-workflows","artifacts","volume-mount","data-safety"],"backgroundTag":"artifact-path-overlaps-volume-mount","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}