{"record":{"id":"58d1e3944f89b61b","repo":"plandex-ai/plandex","slug":"failed-to-get-file-info-for-s-v","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_auto_load.go","lineNumber":49,"sourceCode":"\tfilesSkippedTooLarge := []filePathWithSize{}\n\tfilesSkippedAfterSizeLimit := []string{}\n\n\tvar mu sync.Mutex\n\terrCh := make(chan error, len(files))\n\n\tfor i, path := range files {\n\t\ttotalContexts++\n\t\tif totalContexts > shared.MaxContextCount {\n\t\t\tlog.Println(\"Skipping file\", path, \"because it would exceed the max context count\", totalContexts)\n\t\t\tfilesSkippedAfterSizeLimit = append(filesSkippedAfterSizeLimit, path)\n\t\t\terrCh <- nil\n\t\t\tcontinue\n\t\t}\n\n\t\tgo func(index int, path string) {\n\t\t\tfileInfo, err := os.Stat(path)\n\t\t\tif err != nil {\n\t\t\t\terrCh <- fmt.Errorf(\"failed to get file info for %s: %v\", path, err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif fileInfo.IsDir() {\n\t\t\t\tlog.Println(\"Skipping directory\", path)\n\t\t\t\terrCh <- nil // skip directories\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tsize := fileInfo.Size()\n\n\t\t\tmu.Lock()\n\t\t\tif size > shared.MaxContextBodySize {\n\t\t\t\tlog.Println(\"Skipping file\", path, \"because it's too large\", size)\n\t\t\t\tfilesSkippedTooLarge = append(filesSkippedTooLarge, filePathWithSize{Path: path, Size: size})\n\t\t\t\tmu.Unlock()\n\t\t\t\terrCh <- nil\n\t\t\t\treturn","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/context_auto_load.go#L31-L67","documentation":"Inside a goroutine spawned by AutoLoadContextFiles, os.Stat fails on one of the requested file paths and the error is sent to errCh (which the collector re-wraps as \"failed to load context\"). It means the path does not exist, is inaccessible, or has a malformed name — so the file's info (size, directory check) cannot be gathered.","triggerScenarios":"os.Stat(path) errors in the per-file goroutine: the file was deleted between listing and stat, the path contains a glob/tilde that was never expanded, permission denied on a parent directory, a symlink loop (too many levels), or a path > PATH_MAX.","commonSituations":"Users passing shell-style patterns (~/file, *.go) directly instead of expanded paths, stale file lists referencing files removed by a build or git checkout, running as a user without read access to a project directory, or broken symlinks.","solutions":["Expand ~ and glob patterns before passing paths into AutoLoadContextFiles.","Verify each path exists (os.Stat) and filter out missing/broken entries before loading.","Fix permissions on the file and its parent directories.","Clean up or resync the file list if it references files deleted by git operations or builds.","Optionally skip missing files with a warning instead of failing the entire load."],"exampleFix":"// before\nAutoLoadContextFiles(ctx, []string{\"~/notes.md\", \"*.go\"})\n// after\nvar paths []string\nfor _, p := range []string{\"~/notes.md\", \"*.go\"} {\n    expanded, err := expandPathAndGlob(p) // resolves ~ and globs\n    if err != nil { continue }\n    if _, err := os.Stat(expanded); err == nil { paths = append(paths, expanded) }\n}\nresult, err := AutoLoadContextFiles(ctx, paths)","handlingStrategy":"validation","validationCode":"func filterExistingPaths(paths []string) []string {\n    var ok []string\n    for _, p := range paths {\n        p = expandHome(p) // resolve ~\n        if matches, _ := filepath.Glob(p); len(matches) > 0 {\n            ok = append(ok, matches...)\n        } else if _, err := os.Stat(p); err == nil {\n            ok = append(ok, p)\n        }\n    }\n    return ok\n}","typeGuard":null,"tryCatchPattern":"fileInfo, err := os.Stat(path)\nif err != nil {\n    if os.IsNotExist(err) {\n        log.Printf(\"skipping missing file %s\", path)\n        errCh <- nil\n        return\n    }\n    errCh <- fmt.Errorf(\"failed to get file info for %s: %v\", path, err)\n    return\n}","preventionTips":["Expand ~ and glob patterns before passing paths to the loader.","Re-verify file lists after git operations or builds that move files.","Check read permissions on files and parent directories.","Prefer skipping missing files with warnings over failing the whole batch."],"tags":["filesystem","os-stat","path-resolution","concurrency"],"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"}