sipeed/picoclaw · error

invalid base64 image data

Error message

invalid base64 image data

What it means

Thrown by validateInlineImageDataURL when base64.StdEncoding.DecodeString rejects the trimmed body of the data URL. StdEncoding strictly requires the standard alphabet (A-Z, a-z, 0-9, +, /), correct = padding, and no whitespace inside the body (only leading/trailing spaces are trimmed by the preceding strings.TrimSpace). Any deviation — URL-safe alphabet, missing padding, embedded newlines, truncation — fails here.

Source

Thrown at pkg/channels/pico/pico.go:1410

	header, data, found := strings.Cut(mediaURL, ",")
	if !found || strings.TrimSpace(data) == "" {
		return fmt.Errorf("image data URL is malformed")
	}
	if !strings.Contains(header, ";base64") {
		return fmt.Errorf("image data URL must be base64 encoded")
	}
	mimeType, _, _ := strings.Cut(strings.TrimPrefix(header, "data:"), ";")
	if _, ok := allowedInlineImageMIMETypes[mimeType]; !ok {
		return fmt.Errorf("unsupported image format: %s", mimeType)
	}

	data = strings.TrimSpace(data)
	if base64.StdEncoding.DecodedLen(len(data)) > config.DefaultMaxMediaSize {
		return fmt.Errorf("image exceeds %d byte limit", config.DefaultMaxMediaSize)
	}
	if _, err := base64.StdEncoding.DecodeString(data); err != nil {
		return fmt.Errorf("invalid base64 image data")
	}

	return nil
}

// setContextUsagePayload adds context window usage stats to a pico payload.
func setContextUsagePayload(payload map[string]any, u *bus.ContextUsage) {
	if u == nil {
		return
	}
	payload["context_usage"] = map[string]any{
		"used_tokens":         u.UsedTokens,
		"total_tokens":        u.TotalTokens,
		"history_tokens":      u.HistoryTokens,
		"compress_at_tokens":  u.CompressAtTokens,
		"summarize_at_tokens": u.SummarizeAtTokens,
		"used_percent":        u.UsedPercent,
	}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Encode with base64.StdEncoding.EncodeToString (padded, standard alphabet) when building data URLs.
  2. Strip internal whitespace/newlines before validation: data = strings.NewReplacer("\n", "", "\r", "", " ", "").Replace(data).
  3. If you receive URL-safe base64, transcode it: decode with base64.URLEncoding (or RawURLEncoding) and re-encode with base64.StdEncoding.
  4. Verify the data URL body length is a multiple of 4 after cleanup (padded standard base64).

Example fix

// before: URL-safe, unpadded — rejected by StdEncoding
dataURL := "data:image/png;base64," + base64.RawURLEncoding.EncodeToString(img)

// after: standard alphabet with padding, no embedded whitespace
import "strings"
clean := strings.NewReplacer("\n", "", "\r", "", " ", "").Replace(rawBody)
dataURL := "data:image/png;base64," + clean // body produced by base64.StdEncoding.EncodeToString
Defensive patterns

Strategy: validation

Validate before calling

func isValidStdBase64Body(dataURL string) bool {
    _, body, ok := strings.Cut(dataURL, ",")
    if !ok { return false }
    body = strings.TrimSpace(body)
    body = strings.NewReplacer("\n", "", "\r", "", " ", "").Replace(body)
    _, err := base64.StdEncoding.DecodeString(body)
    return err == nil
}

Try / catch

// if err != nil && strings.Contains(err.Error(), "invalid base64") -> re-encode the source bytes with base64.StdEncoding and retry once; otherwise surface to sender

Prevention

When it happens

Trigger: Producing the data URL with base64.RawURLEncoding / base64.URLEncoding (uses - and _ instead of + and /), omitting padding with base64.RawStdEncoding, embedding line-wrapped base64 (MIME-style \n every 76 chars), or truncating the payload so the final quantum is incomplete.

Common situations: Code that base64-encodes for JWT/URL contexts (URL-safe) reused for image inlining; copying base64 from PEM or MIME files that contain newlines; a string being trimmed or re-wrapped in transit (JSON, YAML, clipboard) breaking padding; hand-assembling the data URL and dropping trailing '=' characters.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/e2ce2c515294036d. Report an issue: GitHub.