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

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.

Source

Thrown at app/cli/lib/context_auto_load.go:49

	filesSkippedTooLarge := []filePathWithSize{}
	filesSkippedAfterSizeLimit := []string{}

	var mu sync.Mutex
	errCh := make(chan error, len(files))

	for i, path := range files {
		totalContexts++
		if totalContexts > shared.MaxContextCount {
			log.Println("Skipping file", path, "because it would exceed the max context count", totalContexts)
			filesSkippedAfterSizeLimit = append(filesSkippedAfterSizeLimit, path)
			errCh <- nil
			continue
		}

		go func(index int, path string) {
			fileInfo, err := os.Stat(path)
			if err != nil {
				errCh <- fmt.Errorf("failed to get file info for %s: %v", path, err)
				return
			}

			if fileInfo.IsDir() {
				log.Println("Skipping directory", path)
				errCh <- nil // skip directories
				return
			}

			size := fileInfo.Size()

			mu.Lock()
			if size > shared.MaxContextBodySize {
				log.Println("Skipping file", path, "because it's too large", size)
				filesSkippedTooLarge = append(filesSkippedTooLarge, filePathWithSize{Path: path, Size: size})
				mu.Unlock()
				errCh <- nil
				return

View on GitHub (pinned to e2d772072e)

Solutions

  1. Expand ~ and glob patterns before passing paths into AutoLoadContextFiles.
  2. Verify each path exists (os.Stat) and filter out missing/broken entries before loading.
  3. Fix permissions on the file and its parent directories.
  4. Clean up or resync the file list if it references files deleted by git operations or builds.
  5. Optionally skip missing files with a warning instead of failing the entire load.

Example fix

// before
AutoLoadContextFiles(ctx, []string{"~/notes.md", "*.go"})
// after
var paths []string
for _, p := range []string{"~/notes.md", "*.go"} {
    expanded, err := expandPathAndGlob(p) // resolves ~ and globs
    if err != nil { continue }
    if _, err := os.Stat(expanded); err == nil { paths = append(paths, expanded) }
}
result, err := AutoLoadContextFiles(ctx, paths)
Defensive patterns

Strategy: validation

Validate before calling

func filterExistingPaths(paths []string) []string {
    var ok []string
    for _, p := range paths {
        p = expandHome(p) // resolve ~
        if matches, _ := filepath.Glob(p); len(matches) > 0 {
            ok = append(ok, matches...)
        } else if _, err := os.Stat(p); err == nil {
            ok = append(ok, p)
        }
    }
    return ok
}

Try / catch

fileInfo, err := os.Stat(path)
if err != nil {
    if os.IsNotExist(err) {
        log.Printf("skipping missing file %s", path)
        errCh <- nil
        return
    }
    errCh <- fmt.Errorf("failed to get file info for %s: %v", path, err)
    return
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/58d1e3944f89b61b. Report an issue: GitHub.