charmbracelet/crush · error
error reading image file: %w
Error message
error reading image file: %w
What it means
The target is a supported image and os.ReadFile(filePath) failed after the size check and stat succeeded — meaning the file became unreadable between stat and read, or I/O failed. Common wrapped causes: EACCES (permissions changed), EIO, or the file being deleted in the race window.
Source
Thrown at internal/agent/tools/view.go:216
} else {
params.Limit = DefaultReadLimit
}
}
isSupportedImage, mimeType := getImageMimeType(filePath)
if isSupportedImage {
if fileInfo.Size() > MaxViewSize {
return fantasy.NewTextErrorResponse(fmt.Sprintf("Image file is too large (%d bytes). Maximum size is %d bytes",
fileInfo.Size(), MaxViewSize)), nil
}
if !GetSupportsImagesFromContext(ctx) {
modelName := GetModelNameFromContext(ctx)
return fantasy.NewTextErrorResponse(fmt.Sprintf("This model (%s) does not support image data.", modelName)), nil
}
imageData, readErr := os.ReadFile(filePath)
if readErr != nil {
return fantasy.ToolResponse{}, fmt.Errorf("error reading image file: %w", readErr)
}
// Some tools save files with a mismatched extension
// (e.g. pinchtab writes JPEG bytes to a .png file).
// Providers like Anthropic strictly validate the
// media type against the base64 magic bytes and 400
// on mismatch, so prefer the sniffed type whenever
// it identifies a supported image format.
mimeType = sniffImageMimeType(imageData, mimeType)
return fantasy.NewImageResponse(imageData, mimeType), nil
}
// Read the file content
maxContentSize := MaxViewSize
if isSkillFile {
maxContentSize = 0
}View on GitHub (pinned to 7944b8e522)
Solutions
- Read the wrapped cause and fix it (permissions, path, mount)
- Confirm the image still exists and is readable by the process user (ls -l)
- Retry — transient I/O errors on network mounts often succeed on a second attempt
- Copy the image to an accessible location before viewing
Example fix
// before // screenshot deleted between stat and read // after cp /tmp/app/screenshot.png ~/shots/ && view ~/shots/screenshot.png
Defensive patterns
Strategy: retry
Validate before calling
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("image %q unreadable: %w", path, err)
}
f.Close() Type guard
func readableImage(path string) bool {
f, err := os.Open(path)
if err != nil { return false }
f.Close()
return true
} Try / catch
var pe *fs.PathError
if errors.As(err, &pe) {
if pe.Err == syscall.EACCES || os.IsNotExist(pe.Err) {
// fix perms / regenerate the image, then retry
}
} Prevention
- Copy generated images to a stable, user-readable location before viewing
- Don't delete or chmod files while the tool is reading them
- Retry transient failures on network-mounted storage
When it happens
Trigger: Image file deleted or permissions revoked between os.Stat and os.ReadFile; I/O errors on failing disks or network mounts; reading images on volumes with intermittent access.
Common situations: Generated screenshots/artifacts in tmpdirs cleaned up concurrently; images on network shares that dropped; files owned by another user with mode 0600.
Related errors
- error reading file: %w
- failed to generate HTML: %w
- failed to create parent directories: %w
- failed to create output file: %w
- failed to write file: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/922a50036a9352d8.
Report an issue: GitHub.