{"record":{"id":"6c41ee83148a62db","repo":"plandex-ai/plandex","slug":"failed-to-check-if-s-exists-s","errorCode":null,"errorMessage":"failed to check if %s exists: %s","messagePattern":"failed to check if (.+?) exists: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/apply.go","lineNumber":651,"sourceCode":"\t\t\terrCh <- nil\n\t\t\tcontinue\n\t\t}\n\t\tgo func(path, content string) {\n\t\t\t// Compute destination path\n\t\t\tdstPath := filepath.Join(fs.ProjectRoot, path)\n\t\t\tcontent = strings.ReplaceAll(content, \"\\\\`\\\\`\\\\`\", \"```\")\n\t\t\t// Check if the file exists\n\t\t\tvar exists bool\n\t\t\tvar mode os.FileMode\n\t\t\tinfo, err := os.Stat(dstPath)\n\t\t\tif err == nil {\n\t\t\t\texists = true\n\t\t\t\tmode = info.Mode()\n\t\t\t} else {\n\t\t\t\tif os.IsNotExist(err) {\n\t\t\t\t\texists = false\n\t\t\t\t} else {\n\t\t\t\t\terrCh <- fmt.Errorf(\"failed to check if %s exists: %s\", dstPath, err.Error())\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif exists {\n\t\t\t\t// read file content\n\t\t\t\tbytes, err := os.ReadFile(dstPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\terrCh <- fmt.Errorf(\"failed to read %s: %s\", dstPath, err.Error())\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// Check if the file has changed\n\t\t\t\tif string(bytes) == content {\n\t\t\t\t\t// log.Println(\"File is unchanged, skipping\")\n\t\t\t\t\terrCh <- nil\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tmu.Lock()","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/apply.go#L633-L669","documentation":"Inside ApplyFiles, each goroutine stats the destination file to determine existence and mode before writing. If os.Stat fails with an error other than NotExist (e.g. permission denied on a parent directory), the goroutine sends this error on errCh, aborting the whole apply.","triggerScenarios":"os.Stat(dstPath) returns an error that is not os.IsNotExist — permission denied on a parent directory, I/O error, or a component of dstPath is not a directory.","commonSituations":"Project subdirectory owned by another user or read-only; dstPath collides with a regular file (e.g. 'pkg' exists as a file but path is 'pkg/x.go'); filesystem/permission issues after running as different users.","solutions":["Check permissions on the target directory (ls -la) and fix with chmod/chown","Verify no file exists where a directory is expected in the path (e.g. 'pkg' is a file)","Run the CLI with sufficient privileges, or from the correct project root","Check disk/filesystem health if I/O errors appear"],"exampleFix":"// before\n$ ls -la pkg   # pkg is a regular file, but plan writes pkg/x.go\n// after\n$ rm pkg && mkdir pkg\n$ plandex apply","handlingStrategy":"validation","validationCode":"// before apply: ensure each path component allows stat\nfor _, path := range paths {\n  if _, err := os.Stat(filepath.Join(root, path)); err != nil && !os.IsNotExist(err) {\n    return fmt.Errorf(\"cannot access %s: %w\", path, err)\n  }\n}","typeGuard":"func statAccessible(path string) bool {\n  _, err := os.Stat(path)\n  return err == nil || os.IsNotExist(err) // NotExist is fine; anything else is a problem\n}","tryCatchPattern":"if _, err := os.Stat(dstPath); err != nil && !os.IsNotExist(err) {\n  return fmt.Errorf(\"stat %s: %w\", dstPath, err)\n}","preventionTips":["Don't create regular files where plan directories are expected","Run the CLI as a user with access to the whole project tree","Fix odd permissions/ownership after switching users (sudo, containers)","Check mount health if EIO appears"],"tags":["go","filesystem","permissions"],"backgroundTag":"file-stat-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}