{"record":{"id":"85364505bd272251","repo":"multica-ai/multica","slug":"remove-stale-s-copy-s-w","errorCode":null,"errorMessage":"remove stale %s copy %s: %w","messagePattern":"remove stale (.+?) copy (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/daemon/execenv/codex_home.go","lineNumber":1024,"sourceCode":"// else would have the daemon delete and overwrite the link target on the next\n// prepare. os.Root still allows links that stay inside the task home, which is\n// harmless, and rejects the ones that leave it. The root itself is\n// identity-checked by openVerifiedCodexHomeRoot.\nfunc materialiseInCodexHome(codexHome, relPath, src, key string) error {\n\troot, err := openVerifiedCodexHomeRoot(codexHome, key)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer root.Close()\n\n\tif dir := filepath.Dir(relPath); dir != \".\" {\n\t\tif err := root.MkdirAll(dir, 0o755); err != nil {\n\t\t\treturn fmt.Errorf(\"create %s directory %s: %w\", key, dir, err)\n\t\t}\n\t}\n\tif _, err := root.Lstat(relPath); err == nil {\n\t\tif err := root.Remove(relPath); err != nil {\n\t\t\treturn fmt.Errorf(\"remove stale %s copy %s: %w\", key, relPath, err)\n\t\t}\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"stat %s copy %s: %w\", key, relPath, err)\n\t}\n\n\tin, err := os.Open(src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open %s %s: %w\", key, src, err)\n\t}\n\tdefer in.Close()\n\n\tout, err := root.OpenFile(relPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create %s copy %s: %w\", key, relPath, err)\n\t}\n\tdefer out.Close()\n\n\tif _, err := io.Copy(out, in); err != nil {","sourceCodeStart":1006,"sourceCodeEnd":1042,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/daemon/execenv/codex_home.go#L1006-L1042","documentation":"Before copying a fresh copy of a config file into the task home, a stale existing copy is removed via root.Remove. Failure means the old file could not be deleted: it is a non-empty directory, permissions deny unlink, or the path crossed an escaping symlink (rejected by os.Root).","triggerScenarios":"relPath exists as a directory with children; the daemon lacks write permission on the containing directory; the existing entry is a symlink whose target resolution os.Root refuses.","commonSituations":"A task replaced a config path (e.g. auth.json) with a directory of its own; reused home with corrupted state.","solutions":["Manually inspect and remove the stale entry under the task home","Recreate the task home if the stale entry is unexpected","Verify the daemon user can write to the task home"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"if fi, err := os.Lstat(filepath.Join(codexHome, relPath)); err == nil && fi.IsDir() {\n\treturn fmt.Errorf(\"cannot replace directory %s with file copy\", relPath)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Fail prepares fast when the destination is a non-empty directory","Recreate reused homes that tasks may have mutated"],"tags":["filesystem","codex-home","stale-state"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}