{"record":{"id":"0d6d71b847f0e5c6","repo":"plandex-ai/plandex","slug":"failed-to-get-file-info-for-s-v-0d6d71","errorCode":null,"errorMessage":"failed to get file info for %s: %v","messagePattern":"failed to get file info for (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/context_load.go","lineNumber":457,"sourceCode":"\t\t\t\t\tif !params.DefsOnly {\n\t\t\t\t\t\tcomposite := strings.Join([]string{string(contextType), path}, \"|\")\n\t\t\t\t\t\tif existsByComposite[composite] != nil {\n\t\t\t\t\t\t\talreadyLoadedByComposite[composite] = existsByComposite[composite]\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tnumRoutines++\n\n\t\t\t\t\tgo func(path string) {\n\t\t\t\t\t\tsem <- struct{}{}\n\t\t\t\t\t\tdefer func() { <-sem }()\n\n\t\t\t\t\t\tvar size int64\n\n\t\t\t\t\t\tfileInfo, err := os.Stat(path)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrCh <- fmt.Errorf(\"failed to get file info for %s: %v\", path, err)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsize = fileInfo.Size()\n\n\t\t\t\t\t\tif !params.DefsOnly && size > shared.MaxContextBodySize {\n\t\t\t\t\t\t\tcontextMu.Lock()\n\t\t\t\t\t\t\tfilesSkippedTooLarge = append(filesSkippedTooLarge, filePathWithSize{Path: path, Size: size})\n\t\t\t\t\t\t\tcontextMu.Unlock()\n\t\t\t\t\t\t\terrCh <- nil\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif !params.DefsOnly {\n\t\t\t\t\t\t\tcontextMu.Lock()\n\t\t\t\t\t\t\tif totalSize+size > shared.MaxContextBodySize {\n\t\t\t\t\t\t\t\tfilesSkippedAfterSizeLimit = append(filesSkippedAfterSizeLimit, path)\n\t\t\t\t\t\t\t\tcontextMu.Unlock()\n\t\t\t\t\t\t\t\terrCh <- nil","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/context_load.go#L439-L475","documentation":"Emitted from the per-file goroutine in MustLoadContext when os.Stat(path) fails while gathering file size before loading. After paths were successfully enumerated and ignore-filtered, the file could not be stat'ed — meaning it was deleted or renamed between enumeration and stat, or is inaccessible due to permissions. The error is sent on errCh and the file is skipped.","triggerScenarios":"os.Stat returns an error such as ENOENT (file deleted/renamed after enumeration), EACCES (permission denied on file or parent dir), or a broken symlink being stat'ed.","commonSituations":"Concurrent builds/clean tasks removing generated files during load; files removed by git operations mid-run; unreadable files due to restrictive permissions or root-owned artifacts; TOCTOU races in large repos.","solutions":["Re-run the load once the working tree is static; enumeration-to-stat races vanish on a stable tree.","Check the wrapped os error: ENOENT -> file vanished, EACCES -> fix permissions (chmod/chown or run with adequate rights).","Verify symlinks in the target paths are not broken (ls -L / readlink).","Stop concurrent processes (codegen, tests, git hooks) that delete or rename files while loading."],"exampleFix":"// before: file deleted between scan and stat\n$ plandex load ./dist\n// error: failed to get file info for ./dist/app.js: stat ./dist/app.js: no such file or directory\n// after: rebuild/generate first so the tree is complete, then load\n$ npm run build && plandex load ./dist","handlingStrategy":"try-catch","validationCode":"// pre-check every path is stat-able before loading\nfor _, p := range inputPaths {\n    if _, err := os.Stat(p); err != nil {\n        return fmt.Errorf(\"cannot stat %s before load: %w\", p, err)\n    }\n}","typeGuard":"func fileAccessible(path string) bool {\n    info, err := os.Stat(path)\n    return err == nil && info.Mode().IsRegular()\n}","tryCatchPattern":"if err := loadContextErr; err != nil {\n    var statErr *fs.PathError\n    if strings.Contains(err.Error(), \"failed to get file info for\") {\n        // file vanished or unreadable between enumeration and stat\n        log.Printf(\"skipping load, tree changed or unreadable: %v\", err)\n        // regenerate/rebuild outputs, fix permissions, then retry once\n        return retryLoad(inputPaths)\n    }\n    return err\n}","preventionTips":["Freeze the tree during load: no concurrent builds, cleanups, or git operations.","Fix permissions on generated artifacts (common with Docker/root-created files).","Check for broken symlinks in target directories before loading.","Treat this as transient: rebuild the outputs and retry the load."],"tags":["go","filesystem","toctou","os-stat"],"backgroundTag":"file-not-found","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"}