plandex-ai/plandex · error
failed to get file info for %s: %v
Error message
failed to get file info for %s: %v
What it means
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.
Source
Thrown at app/cli/lib/context_load.go:457
if !params.DefsOnly {
composite := strings.Join([]string{string(contextType), path}, "|")
if existsByComposite[composite] != nil {
alreadyLoadedByComposite[composite] = existsByComposite[composite]
continue
}
}
numRoutines++
go func(path string) {
sem <- struct{}{}
defer func() { <-sem }()
var size int64
fileInfo, err := os.Stat(path)
if err != nil {
errCh <- fmt.Errorf("failed to get file info for %s: %v", path, err)
return
}
size = fileInfo.Size()
if !params.DefsOnly && size > shared.MaxContextBodySize {
contextMu.Lock()
filesSkippedTooLarge = append(filesSkippedTooLarge, filePathWithSize{Path: path, Size: size})
contextMu.Unlock()
errCh <- nil
return
}
if !params.DefsOnly {
contextMu.Lock()
if totalSize+size > shared.MaxContextBodySize {
filesSkippedAfterSizeLimit = append(filesSkippedAfterSizeLimit, path)
contextMu.Unlock()
errCh <- nilView on GitHub (pinned to e2d772072e)
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.
Example fix
// before: file deleted between scan and stat $ plandex load ./dist // error: failed to get file info for ./dist/app.js: stat ./dist/app.js: no such file or directory // after: rebuild/generate first so the tree is complete, then load $ npm run build && plandex load ./dist
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check every path is stat-able before loading
for _, p := range inputPaths {
if _, err := os.Stat(p); err != nil {
return fmt.Errorf("cannot stat %s before load: %w", p, err)
}
} Type guard
func fileAccessible(path string) bool {
info, err := os.Stat(path)
return err == nil && info.Mode().IsRegular()
} Try / catch
if err := loadContextErr; err != nil {
var statErr *fs.PathError
if strings.Contains(err.Error(), "failed to get file info for") {
// file vanished or unreadable between enumeration and stat
log.Printf("skipping load, tree changed or unreadable: %v", err)
// regenerate/rebuild outputs, fix permissions, then retry once
return retryLoad(inputPaths)
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- error loading accounts: %v
- no project root found
- error getting git root: %s
- error getting files in git repo: %s
- error walking directory: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/0d6d71b847f0e5c6.
Report an issue: GitHub.