{"record":{"id":"651e13b3e945a2cf","repo":"plandex-ai/plandex","slug":"error-reading-file-v","errorCode":null,"errorMessage":"error reading file: %v","messagePattern":"error reading file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/syntax/file_map/cli/main.go","lineNumber":52,"sourceCode":"\n\tpaths := args\n\n\tvar filteredPaths []string\n\tfor _, path := range paths {\n\t\tif shared.HasFileMapSupport(path) {\n\t\t\tfilteredPaths = append(filteredPaths, path)\n\t\t}\n\t}\n\n\terrCh := make(chan error, len(filteredPaths))\n\tfileInputs := map[string]string{}\n\tvar mu sync.Mutex\n\n\tfor _, path := range filteredPaths {\n\t\tgo func(path string) {\n\t\t\tcontent, err := os.ReadFile(path)\n\t\t\tif err != nil {\n\t\t\t\terrCh <- fmt.Errorf(\"error reading file: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tmu.Lock()\n\t\t\tfileInputs[path] = string(content)\n\t\t\tmu.Unlock()\n\t\t\terrCh <- nil\n\t\t}(path)\n\t}\n\n\tfor i := 0; i < len(filteredPaths); i++ {\n\t\terr := <-errCh\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"error reading file: %v\\n\", err)\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n\n\tif parserTree {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/syntax/file_map/cli/main.go#L34-L70","documentation":"In the file_map CLI, each filtered path is read with os.ReadFile in a goroutine. If the read fails (file missing, permission denied, is a directory, etc.) the goroutine pushes an 'error reading file: %v' wrapping the os error onto the error channel instead of mapping the file. It is a pass-through of the underlying OS I/O failure.","triggerScenarios":"Running the file_map CLI on paths that don't exist, aren't readable by the current user, are directories rather than files, or that were deleted between path filtering and reading (race with filesystem changes).","commonSituations":"Typo'd or stale file list, running the tool as a user lacking read permissions, reading symlink targets that point nowhere, reading directories not pruned by the filter step.","solutions":["Verify each path exists and is a regular file (os.Stat) before/while filtering","Check file permissions for the user running the CLI","Re-run after refreshing the path list if files changed concurrently","Wrap paths in absolute form relative to the intended working directory"],"exampleFix":"// before\nfilteredPaths, _ := collectPaths(root)\nrunMap(filteredPaths)\n// after\nfor _, p := range filteredPaths {\n    if fi, err := os.Stat(p); err != nil || fi.IsDir() {\n        log.Printf(\"skipping unreadable path %s: %v\", p, err)\n        continue\n    }\n}\nrunMap(filteredPaths)","handlingStrategy":"validation","validationCode":"info, err := os.Stat(path)\nif err != nil || info.IsDir() {\n    return fmt.Errorf(\"skip %s: %v\", path, err)\n}\nif file, err := os.Open(path); err != nil {\n    return fmt.Errorf(\"unreadable %s: %v\", path, err)\n} else { file.Close() }","typeGuard":"func readableFile(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.Mode().IsRegular()\n}","tryCatchPattern":"if err := runCLI(paths); err != nil && strings.HasPrefix(err.Error(), \"error reading file:\") {\n    log.Printf(\"file access problem: %v — check path/permissions\", err)\n}","preventionTips":["Stat every path before feeding it to the CLI","Filter out directories and symlinks with missing targets","Run with a user that has read access to the target tree","Refresh file lists immediately before reading to avoid races"],"tags":["file-io","go","os","cli"],"backgroundTag":"file-read-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"}