plandex-ai/plandex · error
failed to read file %s: %v
Error message
failed to read file %s: %v
What it means
For non-truncated files, getMapFileDetails performs a partial read for the map via getMapFileContent and wraps any failure with this message. It means the file's content (and its sha) could not be read from disk, so the map entry for this file cannot be produced.
Source
Thrown at app/cli/lib/context_shared.go:84
totalMapSizeExceeded = true
res.mapFilesSkippedAfterSizeLimit = append(res.mapFilesSkippedAfterSizeLimit, path)
res.tokens = shared.GetBytesToTokensEstimate(size)
} else if truncated {
res.mapFilesTruncatedTooLarge = append(res.mapFilesTruncatedTooLarge, filePathWithSize{Path: path, Size: size})
}
}
if totalMapSizeExceeded || !shared.HasFileMapSupport(path) || isImage {
shaVal := sha256.Sum256([]byte(fmt.Sprintf("%d", res.tokens)))
res.shaVal = hex.EncodeToString(shaVal[:])
res.mapContent = ""
res.size = 0
} else {
// partial read for the map
contentRes, err := getMapFileContent(path)
if err != nil {
return mapFileDetails{}, fmt.Errorf("failed to read file %s: %v", path, err)
}
res.mapContent = contentRes.content
res.shaVal = contentRes.shaVal
if contentRes.truncated {
res.mapFilesTruncatedTooLarge = append(res.mapFilesTruncatedTooLarge, filePathWithSize{Path: path, Size: shared.MaxContextMapSingleInputSize})
res.size = shared.MaxContextMapSingleInputSize
res.tokens = shared.GetBytesToTokensEstimate(shared.MaxContextMapSingleInputSize)
} else {
// do the actual token count if we didn't truncate
res.tokens = shared.GetNumTokensEstimate(res.mapContent)
}
}
return res, nil
}
View on GitHub (pinned to e2d772072e)
Solutions
- Check the file exists and is readable by the current user (ls -l / chmod)
- Restore deleted files (git checkout -- <file>) and re-run
- Exclude unreadable files from the context paths
Example fix
// before
contentRes, err := getMapFileContent(path)
if err != nil {
return mapFileDetails{}, fmt.Errorf("failed to read file %s: %v", path, err)
}
// after
contentRes, err := getMapFileContent(path)
if err != nil {
if os.IsPermission(err) {
fmt.Printf("skipping unreadable file %s\n", path)
return mapFileDetails{}, nil
}
return mapFileDetails{}, fmt.Errorf("failed to read file %s: %w", path, err)
} Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("file %s missing: %w", path, err)
}
if !info.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", path)
}
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("file %s not readable: %w", path, err)
}
f.Close() Type guard
func isReadableRegularFile(path string) bool {
info, err := os.Stat(path)
if err != nil || !info.Mode().IsRegular() { return false }
f, err := os.Open(path)
if err != nil { return false }
f.Close()
return true
} Try / catch
contentRes, err := getMapFileContent(path)
if err != nil {
if os.IsPermission(err) {
fmt.Printf("skipping unreadable file %s\n", path)
} else {
return fmt.Errorf("failed to read file %s: %w", path, err)
}
} Prevention
- Check file permissions before mapping large trees
- Avoid mutating the working tree (git clean/checkout) while mapping
- Exclude generated or encrypted files from context paths
When it happens
Trigger: getMapFileContent(path) returns an error during map building — permission-denied reads, file deleted mid-operation, or I/O errors on large/binary files.
Common situations: Files with restrictive permissions (root-owned, chmod 000); files removed by git checkout/clean while the command runs; encrypted or filesystem-corrupted files.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to open file %s: %w
- error creating account credentials directory: %v
- error writing account credentials: %v
- error checking model settings file: %v
- error reading settings-v2.json: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/65b77438975940bc.
Report an issue: GitHub.