plandex-ai/plandex · error
failed to decode image config: %w
Error message
failed to decode image config: %w
What it means
After decoding, GetImageTokensFromHeader calls image.DecodeConfig, which sniffs the image header (gif/jpeg/png/webp registered via blank imports) to read dimensions. This error means the bytes are not a decodable/registered image format or the header is corrupt/truncated.
Source
Thrown at app/shared/images.go:38
_ "golang.org/x/image/webp"
)
func GetImageTokens(base64Image string, detail openai.ImageURLDetail) (int, error) {
imageData, err := base64.StdEncoding.DecodeString(base64Image)
if err != nil {
log.Println("failed to decode base64 image data:", err)
return 0, fmt.Errorf("failed to decode base64 image data: %w", err)
}
return GetImageTokensFromHeader(bytes.NewReader(imageData), detail, int64(len(imageData)))
}
func GetImageTokensFromHeader(reader io.Reader, detail openai.ImageURLDetail, maxBytes int64) (int, error) {
reader = io.LimitReader(reader, maxBytes)
img, _, err := image.DecodeConfig(reader)
if err != nil {
log.Println("failed to decode image config:", err)
return 0, fmt.Errorf("failed to decode image config: %w", err)
}
width, height := img.Width, img.Height
anthropicTokens := getAnthropicImageTokens(width, height)
googleTokens := getGoogleImageTokens(width, height)
openaiTokens := getOpenAIImageTokens(width, height, detail)
// log.Printf("GetImageTokens - width: %d, height: %d\n", width, height)
// log.Printf("GetImageTokens - anthropicTokens: %d\n", anthropicTokens)
// log.Printf("GetImageTokens - googleTokens: %d\n", googleTokens)
// log.Printf("GetImageTokens - openaiTokens: %d\n", openaiTokens)
// get max of the three
return int(math.Max(
float64(anthropicTokens),
math.Max(
float64(googleTokens),View on GitHub (pinned to e2d772072e)
Solutions
- Register additional decoders with blank imports (e.g. _ "golang.org/x/image/tiff") if the format is supported upstream.
- Reject or skip unsupported formats (SVG, AVIF, HEIC) with a user-facing validation before token estimation.
- Validate that the image bytes begin with a known magic number (PNG \x89PNG, JPEG \xFF\xD8, GIF87a/GIF89a, RIFF....WEBP) before calling.
- Ensure maxBytes covers the full header (pass the complete byte length, as GetImageTokens does with int64(len(imageData))).
Example fix
// before
_, _, err := image.DecodeConfig(bytes.NewReader(raw)) // fails for SVG/AVIF
// after
if !isValidImageMagic(raw) { // check PNG/JPEG/GIF/WEBP magic bytes
return fmt.Errorf("unsupported image format")
}
img, _, err := image.DecodeConfig(bytes.NewReader(raw)) Defensive patterns
Strategy: validation
Validate before calling
func hasKnownImageMagic(b []byte) bool {
if len(b) < 12 { return false }
png := bytes.HasPrefix(b, []byte{"\x89PNG\r\n\x1a\n"})
jpeg := bytes.HasPrefix(b, []byte{"\xFF\xD8\xFF"})
gif := bytes.HasPrefix(b, []byte("GIF87a")) || bytes.HasPrefix(b, []byte("GIF89a"))
webp := bytes.HasPrefix(b, []byte("RIFF")) && bytes.Equal(b[8:12], []byte("WEBP"))
return png || jpeg || gif || webp
} Try / catch
tokens, err := shared.GetImageTokens(payload, detail)
if err != nil {
if strings.Contains(err.Error(), "failed to decode image config") {
return fmt.Errorf("unsupported or corrupt image (use PNG/JPEG/GIF/WEBP): %w", err)
}
return err
} Prevention
- Only accept PNG, JPEG, GIF, and WEBP uploads; reject SVG/AVIF/HEIC explicitly.
- Verify magic bytes in the upload handler before persisting.
- Ensure uploads are complete (check content-length vs received bytes).
- Pass the full payload length as maxBytes so headers are never clipped.
When it happens
Trigger: Passing decoded bytes whose format is not registered (e.g. SVG, TIFF, AVIF, HEIC); corrupt or truncated image data; an empty reader; maxBytes too small so DecodeConfig cannot read a full header.
Common situations: Users uploading SVGs or AVIF images which the model pipeline treats as images but image.DecodeConfig cannot parse; partially uploaded files; wrong maxBytes argument clipping the header.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error getting num tokens: %v
- failed to decode base64 image data: %w
- connection to plan stream timed out due to missing heartbeat
- error loading accounts: %v
- error signing in to new account: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/3608834169716ea5.
Report an issue: GitHub.