Hmbown/CodeWhale · error

images exceed the 5 MiB total limit

Error message

images exceed the 5 MiB total limit

What it means

The cumulative decoded size of all images in one prepare_images_with_limit call exceeds the total budget (5 MiB); the running total is checked after each image and bails as soon as it crosses total_limit. Individual images can each be under the per-image cap while together exceeding the aggregate cap.

Solutions

  1. Attach fewer images per call or split them across multiple requests.
  2. Compress each image so the batch total stays under 5 MiB.
  3. Pre-compute the sum of decoded sizes in the caller and trim the batch before attaching.
  4. Prioritize the 1–2 images that matter and describe the rest in text.

Example fix

// before
let blocks = prepare_runtime_images(&screenshots)?;  // 6 x ~1MiB
// after
let blocks = prepare_runtime_images(&screenshots.into_iter().take(3).collect::<Vec<_>>())?;
Defensive patterns

Strategy: validation

Validate before calling

let total: usize = images.iter()
    .filter_map(|i| STANDARD.decode(&i.data_base64).ok().map(|b| b.len()))
    .sum();
if total > MAX_RUNTIME_IMAGE_TOTAL_BYTES { /* trim the batch */ }

Try / catch

match prepare_runtime_images(&images) {
    Err(e) if e.to_string().contains("total limit") => {
        eprintln!("batch exceeds 5 MiB total; attach fewer or smaller images"); }
    other => other?,
}

Prevention

When it happens

Trigger: prepare_runtime_images (which passes Some(MAX_RUNTIME_IMAGE_TOTAL_BYTES)) or prepare_stored_images with several images whose decoded sizes sum past the total limit — e.g. five 1.2 MiB screenshots in one attach batch.

Common situations: Attaching multiple screenshots of a long page; a multi-image bug report; looping over files and attaching all of them in one request.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/40edce17e9015b6e. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/image_attach.rs:152

                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 {
                bail!("image {} base64 is not canonical", index + 1);
            }
            Ok(attached.content_block())
        })
        .collect()
}

/// Reuse durable canonical bytes for retry, never reread a path or URL.
pub(crate) fn runtime_images_from_blocks(
    blocks: &[ContentBlock],

View on GitHub (pinned to 73e0f67d83)