plandex-ai/plandex · error

failed to decode base64 image data: %w

Error message

failed to decode base64 image data: %w

What it means

GetImageTokens first decodes its base64Image argument with base64.StdEncoding.DecodeString; if that fails (the string is not valid standard-alphabet base64) it wraps the error with this message. The function only accepts raw, unpadded-data standard base64 payloads, not data URIs.

Source

Thrown at app/shared/images.go:27

	"log"
	"math"
	"path/filepath"
	"strings"

	"github.com/sashabaranov/go-openai"

	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"

	_ "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)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Strip the "data:image/...;base64," prefix before calling GetImageTokens.
  2. Trim whitespace and newlines from the payload.
  3. Convert URL-safe base64 to standard by replacing '-' with '+' and '_' with '/'.
  4. Validate the string decodes (e.g. base64.StdEncoding.DecodeString in a check) before passing it in.

Example fix

// before
tokens, err := shared.GetImageTokens(dataURI, openai.ImageURLDetailAuto) // "data:image/png;base64,iVBOR..."
// after
payload := dataURI
if i := strings.Index(payload, ","); i != -1 && strings.HasPrefix(payload, "data:") {
    payload = payload[i+1:]
}
payload = strings.TrimSpace(payload)
tokens, err := shared.GetImageTokens(payload, openai.ImageURLDetailAuto)
Defensive patterns

Strategy: validation

Validate before calling

func isValidBase64Image(s string) bool {
    s = strings.TrimSpace(s)
    if i := strings.Index(s, ","); i != -1 && strings.HasPrefix(s, "data:") {
        s = s[i+1:]
    }
    _, err := base64.StdEncoding.DecodeString(s)
    return err == nil
}

Type guard

func isDataURL(s string) bool {
    return strings.HasPrefix(s, "data:")
}

Try / catch

tokens, err := shared.GetImageTokens(payload, openai.ImageURLDetailAuto)
if err != nil {
    if strings.Contains(err.Error(), "failed to decode base64 image data") {
        return fmt.Errorf("image payload is not valid standard base64: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling shared.GetImageTokens with a data URI prefix like "data:image/png;base64," still attached; whitespace/newlines inside the base64 string; URL-safe base64 (- and _) instead of standard (+ and /); a truncated or empty string.

Common situations: Storing images with data-URI prefixes in DB/JSON and passing them straight to GetImageTokens; base64 produced by URL-safe encoders (e.g. some JWT/web tooling); payloads mangled by line-wrapping in email or config files.

Understand the failure class

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/8341d548e8c310ea. Report an issue: GitHub.