plandex-ai/plandex · error
failed to read image tokens for %s: %v
Error message
failed to read image tokens for %s: %v
What it means
getMapFileDetails detects image files via shared.IsImageFile and estimates their token count with readImageTokensForDefsOnly. If that fails (file unreadable or header parse error), the failure is wrapped with this message naming the image path. It means the image could not be tokenized for the file map.
Source
Thrown at app/cli/lib/context_shared.go:51
func getMapFileDetails(path string, size, mapSize int64) (mapFileDetails, error) {
var isImage bool
var totalMapSizeExceeded bool
res := mapFileDetails{
size: size,
mapFilesSkippedAfterSizeLimit: []string{},
mapFilesTruncatedTooLarge: []filePathWithSize{},
}
if !shared.HasFileMapSupport(path) {
if shared.IsImageFile(path) {
isImage = true
var err error
res.tokens, err = readImageTokensForDefsOnly(path, size, openai.ImageURLDetailHigh, 8*1024)
if err != nil {
return mapFileDetails{}, fmt.Errorf("failed to read image tokens for %s: %v", path, err)
}
} else {
res.tokens = shared.GetBytesToTokensEstimate(size)
}
} else {
var truncated bool
if size > shared.MaxContextMapSingleInputSize {
size = shared.MaxContextMapSingleInputSize
truncated = true
res.tokens = shared.GetBytesToTokensEstimate(size)
}
// should go in either skip list *or* truncated list, not both
if mapSize+size > shared.MaxContextMapTotalInputSize {
totalMapSizeExceeded = true
res.mapFilesSkippedAfterSizeLimit = append(res.mapFilesSkippedAfterSizeLimit, path)
res.tokens = shared.GetBytesToTokensEstimate(size)
} else if truncated {View on GitHub (pinned to e2d772072e)
Solutions
- Verify the image file opens and is a valid image (file/permissions check)
- Remove the corrupt or non-image file from the context paths
- If the file is legitimately an image, re-copy or re-download it
Example fix
// before
res.tokens, err = readImageTokensForDefsOnly(path, size, openai.ImageURLDetailHigh, 8*1024)
if err != nil {
return mapFileDetails{}, fmt.Errorf("failed to read image tokens for %s: %v", path, err)
}
// after — fall back to byte-based estimate instead of failing
res.tokens, err = readImageTokensForDefsOnly(path, size, openai.ImageURLDetailHigh, 8*1024)
if err != nil {
res.tokens = shared.GetImageTokensEstimateFromBytes(size)
} Defensive patterns
Strategy: fallback
Validate before calling
if shared.IsImageFile(path) {
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("image %s unreadable: %w", path, err)
}
f.Close()
} Type guard
func isReadableImage(path string) bool {
if !shared.IsImageFile(path) { return false }
f, err := os.Open(path)
if err != nil { return false }
defer f.Close()
head := make([]byte, 8)
_, err = f.Read(head)
return err == nil
} Try / catch
tokens, err := readImageTokensForDefsOnly(path, size, openai.ImageURLDetailHigh, 8*1024)
if err != nil {
tokens = shared.GetImageTokensEstimateFromBytes(size) // graceful fallback
} Prevention
- Verify image files open correctly before adding them to context
- Remove corrupt/zero-byte images from repos used with the tool
- Keep image extensions honest (don't rename text files to .png)
When it happens
Trigger: shared.IsImageFile(path) is true and readImageTokensForDefsOnly(path, size, openai.ImageURLDetailHigh, 8*1024) returns an error — os.Open failure or GetImageTokensFromHeader failure on a corrupt/truncated image header.
Common situations: Binary/corrupt files that pass the image-extension check; permission-denied image files; zero-byte or truncated images copied from a failed download.
Related errors
- failed to open file %s: %w
- error loading accounts: %v
- error setting auth: %v
- error writing auth: %v
- error writing auth: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/4c480348bdde6fa2.
Report an issue: GitHub.