plandex-ai/plandex · error
failed to read file %s: %v
Error message
failed to read file %s: %v
What it means
In the per-file goroutine of AutoLoadContextFiles, os.ReadFile fails after the stat check succeeded, meaning the file became unreadable between stat and read or lacks read permission. The error is sent to errCh and surfaces to the caller as "failed to load context".
Source
Thrown at app/cli/lib/context_auto_load.go:81
log.Println("Skipping file", path, "because it's too large", size)
filesSkippedTooLarge = append(filesSkippedTooLarge, filePathWithSize{Path: path, Size: size})
mu.Unlock()
errCh <- nil
return
}
if totalSize+size > shared.MaxTotalContextSize {
log.Println("Skipping file", path, "because it would exceed the max context body size", totalSize+size)
filesSkippedAfterSizeLimit = append(filesSkippedAfterSizeLimit, path)
mu.Unlock()
errCh <- nil
return
}
totalSize += size
mu.Unlock()
b, err := os.ReadFile(path)
if err != nil {
errCh <- fmt.Errorf("failed to read file %s: %v", path, err)
return
}
var contextType shared.ContextType
isImage := shared.IsImageFile(path)
if isImage {
contextType = shared.ContextImageType
} else {
contextType = shared.ContextFileType
}
var imageDetail openai.ImageURLDetail
if isImage {
imageDetail = openai.ImageURLDetailHigh
}
var body string
if isImage {View on GitHub (pinned to e2d772072e)
Solutions
- Check the file's read permission bits (chmod or run as a user with access).
- Exclude special files: verify mode.Type() == 0 (regular file) after stat, not just !IsDir().
- Handle read races on rotated/deleted files by retrying once or skipping with a warning.
- Ensure the file is closed/unlocked by the writer (e.g. editor swap files, active log rotation) before loading.
- For network mounts, verify mount health and retry.
Example fix
// before
if fileInfo.IsDir() { ... }
b, err := os.ReadFile(path)
// after
if !fileInfo.Mode().IsRegular() {
errCh <- nil // skip dirs, devices, fifos, sockets
return
}
b, err := os.ReadFile(path)
if os.IsPermission(err) {
log.Printf("skipping unreadable file %s: %v", path, err)
errCh <- nil
return
} Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("bad path %s: %w", path, err)
}
if !info.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", path)
}
if f, err := os.Open(path); err != nil {
return fmt.Errorf("%s not readable: %w", path, err)
} else { f.Close() } Try / catch
b, err := os.ReadFile(path)
if err != nil {
switch {
case os.IsPermission(err):
log.Printf("skipping unreadable file %s", path)
errCh <- nil
case os.IsNotExist(err):
log.Printf("file vanished during load: %s", path)
errCh <- nil
default:
errCh <- fmt.Errorf("failed to read file %s: %v", path, err)
}
return
} Prevention
- Skip non-regular files (devices, FIFOs, sockets, /proc entries) after stat.
- Check read permissions before batch-loading; run with an appropriate user.
- Avoid loading actively rotated log files; snapshot or copy them first.
- Retry reads once on transient I/O errors (network mounts).
When it happens
Trigger: os.ReadFile(path) errors: permission denied (file mode or ACL), the file was truncated/rotated/deleted mid-run (race), the "file" is a device/FIFO or /proc-like special file that cannot be read conventionally, or I/O errors (bad sector, network mount drop).
Common situations: Loading log files being actively rotated, reading files owned by another user (e.g. root-only configs), pointing context loading at virtual filesystems (/proc, /sys) or sockets, or NFS/network mounts flaking.
Related errors
- failed to read the file %s: %v
- error reading description file %s: %v
- error deleting result file: %v
- error setting auth: %v
- error writing auth: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/0a8fb5db70632da4.
Report an issue: GitHub.