Hmbown/CodeWhale · error
image has invalid base64
Error message
image {} has invalid base64 What it means
One of the runtime image inputs carried a data_base64 string that is not valid standard base64, so STANDARD.decode() failed. The error names the 1-based image index so the caller knows which attachment to fix.
Solutions
- Re-encode the bytes with standard base64 (with padding) and pass only the payload, stripping any `data:<mime>;base64,` prefix.
- If the source uses URL-safe base64, convert '-_' to '+/' and restore padding before assigning data_base64.
- Strip whitespace/newlines from the base64 string.
Example fix
// before data_base64: "iVBORw0KGgoAAAANSUhEUg..._-" // URL-safe alphabet // after data_base64: "iVBORw0KGgoAAAANSUhEUg...+/=" // standard base64 with padding
Defensive patterns
Strategy: validation
Validate before calling
fn valid_std_base64(s: &str) -> bool {
let cleaned: String = s.chars().filter(|c| !c.is_whitespace()).collect();
base64::engine::general_purpose::STANDARD.decode(&cleaned).is_ok()
} Try / catch
// Rust
match STANDARD.decode(&image.data_base64) {
Ok(bytes) => attach(bytes),
Err(e) => {
let repaired = image.data_base64.replace(['-', '_'], "+/");
attach(STANDARD.decode(repaired.trim())?);
}
} Prevention
- Always encode attachments with standard (padded) base64, never URL-safe variants.
- Store only the base64 payload in data_base64; keep the mime type in the separate mime field.
- Strip whitespace and data-URL prefixes before assigning data_base64.
When it happens
Trigger: prepare_images_with_limit (via prepare_runtime_images or prepare_stored_images) is given a RuntimeImageInput whose data_base64 contains characters outside the standard base64 alphabet, wrong padding, or URL-safe '-_' characters where standard '+/' is required.
Common situations: Producers that URL-safe-encode base64; strings with whitespace, newlines, or a `data:` prefix accidentally included in data_base64; copying a base64 string out of JSON tooling that wrapped or escaped it.
Related errors
- invalid tool image evidence
- image base64 is not canonical
- image exceeds the MiB limit
- image MIME does not match its content
- images exceed the 5 MiB total limit
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c9d85473bf13a4e9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/image_attach.rs:142
images: &[RuntimeImageInput],
per_image_limit: usize,
total_limit: Option<usize>,
) -> Result<Vec<ContentBlock>> {
let mut total = 0usize;
images
.iter()
.enumerate()
.map(|(index, image)| {
if image.data_base64.len() > per_image_limit.div_ceil(3) * 4 {
bail!(
"image {} exceeds the {} MiB limit",
index + 1,
per_image_limit / (1024 * 1024)
);
}
let bytes = STANDARD
.decode(&image.data_base64)
.map_err(|_| anyhow::anyhow!("image {} has invalid base64", index + 1))?;
if bytes.len() > per_image_limit {
bail!(
"image {} exceeds the {} MiB limit",
index + 1,
per_image_limit / (1024 * 1024)
);
}
total = total.saturating_add(bytes.len());
if total_limit.is_some_and(|limit| total > limit) {
bail!("images exceed the 5 MiB total limit");
}
let attached = encode_image_bytes(&bytes, &format!("image {}", index + 1))?;
if image.mime != attached.media_type {
bail!("image {} MIME does not match its content", index + 1);
}
decode_and_guard_image(&bytes)?;
// Standard padded base64 is the one replay representation.
if STANDARD.encode(&bytes) != image.data_base64 {View on GitHub (pinned to 73e0f67d83)