{"record":{"id":"4dda854d48cdbb79","repo":"apache/beam","slug":"failed-to-delete-v-remove-v","errorCode":null,"errorMessage":"failed to delete: %v (remove: %v)","messagePattern":"failed to delete: (.+?) \\(remove: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/artifact/materialize.go","lineNumber":220,"sourceCode":"\ntype artifact struct {\n\tclient         jobpb.ArtifactRetrievalServiceClient\n\tdep            *pipepb.ArtifactInformation\n\texpectedSha256 string\n}\n\nfunc (a artifact) retrieve(ctx context.Context, dest string) error {\n\tpath, err := extractStagingToPath(a.dep)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfilename := filepath.Join(dest, filepath.FromSlash(path))\n\n\t_, err = os.Stat(filename)\n\tif err == nil {\n\t\tif err = os.Remove(filename); err != nil {\n\t\t\treturn errors.Errorf(\"failed to delete: %v (remove: %v)\", filename, err)\n\t\t}\n\t} else if !os.IsNotExist(err) {\n\t\treturn errors.Wrapf(err, \"failed to stat %v\", filename)\n\t}\n\n\tif err := os.MkdirAll(filepath.Dir(filename), os.ModePerm); err != nil {\n\t\treturn err\n\t}\n\n\tstream, err := a.client.GetArtifact(ctx, &jobpb.GetArtifactRequest{Artifact: a.dep})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfd, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0755)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/artifact/materialize.go#L202-L238","documentation":"Returned by artifact.retrieve when an existing file at the destination path cannot be removed before re-downloading the artifact. The library deletes a previously retrieved file so it can rewrite it cleanly; os.Remove failed and the filename plus underlying error are embedded in the message.","triggerScenarios":"Retrieving an artifact into dest when the target file exists but cannot be deleted: the file is a directory at that path, the file is immutable (chattr +i), the filesystem is read-only, or the process lacks write permission on the parent directory.","commonSituations":"dest path collides with a directory of the same name from a previous run with different staging names; running the worker as a non-root user against files created by root or another container layer; a mounted read-only volume as dest; Docker/Kubernetes volume permission mismatch.","solutions":["Ensure dest points to an empty writable directory (e.g. a fresh temp dir) used only for artifact retrieval.","Fix permissions on the destination directory so the process user can delete files in it (chmod/chown the dir).","If the target path is a directory, remove the stale directory before rerunning Materialize.","Run the worker with sufficient privileges or remount the volume read-write."],"exampleFix":"// before: shared, possibly dirty dest\nartifact.Materialize(ctx, endpoint, deps, rt, \"/opt/beam/artifacts\")\n// after: fresh writable staging dir per run\ndest, _ := os.MkdirTemp(\"\", \"beam-artifacts-\")\nartifact.Materialize(ctx, endpoint, deps, rt, dest)","handlingStrategy":"validation","validationCode":"func ensureWritableCleanDir(dest string) error {\n\tinfo, err := os.Stat(dest)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !info.IsDir() {\n\t\treturn fmt.Errorf(\"%s is not a directory\", dest)\n\t}\n\tprobe := filepath.Join(dest, \".probe\")\n\tif err := os.WriteFile(probe, nil, 0o644); err != nil {\n\t\treturn err\n\t}\n\treturn os.Remove(probe)\n}\n// call ensureWritableCleanDir(dest) before Materialize","typeGuard":null,"tryCatchPattern":"if err := artifact.Materialize(ctx, endpoint, deps, rt, dest); err != nil {\n\tif strings.Contains(err.Error(), \"failed to delete\") {\n\t\t// permission/ownership issue at dest: attempt cleanup or fail with guidance\n\t\treturn fmt.Errorf(\"cannot clean dest %s: %w\", dest, err)\n\t}\n\treturn err\n}","preventionTips":["Use a fresh, writable temp directory for artifact retrieval each run.","Never point dest at a directory containing same-named subdirectories or root-owned files.","Verify volume is mounted read-write, not read-only.","Check container user UID matches file ownership on mounted volumes."],"tags":["go","filesystem","permission-denied","beam-artifacts"],"backgroundTag":"file-write-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}