attachment_too_large 413: 30 MB per image, 500 MB per run
A Format run 413 attachment_too_large means one image is over 30 MB or the set is over 500 MB. It is a different 413 from payload_too_large (4 MiB body).

413 attachment_too_large on a Sume Format run means one attached image is over 30 MB, or the images together are over 500 MB. It is not the same error as 413 payload_too_large, which is about the JSON request body being over 4 MiB.
Both are 413, so branching on the HTTP status alone sends you to the wrong fix. The sections below separate them using the Formats guide and Errors and spend.
Which 413 did I get?
Read error.code first. The two codes come from different checks and have different remedies.
A quick rule of thumb: if you inlined something large into the JSON, such as a big input object or text blob, expect payload_too_large. If the JSON is small but it points at heavy image files, expect attachment_too_large. Sume's own advice for the first is to send media by URL, which is also how attachments work, so the two fixes never conflict.
| error.code | Trigger | Fix |
|---|---|---|
| payload_too_large | The request body is over 4 MiB (details.limit_bytes carries the limit). | Shrink input; send media by URL. |
| attachment_too_large | An image is over 30 MB, or the set is over 500 MB. | Resize the images. |
What are the exact attachment limits?
Attachments are the attachments[] array on the create body. The docs list the limits in one table: types are JPEG, PNG, WebP, GIF and AVIF; up to 30 images per run; 30 MB per image; 500 MB per run.
Sume fetches every attachment at create time, checks its real type and size, and copies it into durable storage. That is why this failure arrives on the create call as a 4xx instead of killing the run minutes later. An asset_id or a URL already on media.sume.com is not re-copied.
The size check applies to the file Sume actually downloaded, so a URL that serves a larger original than you expected can trip it even if your local copy was small.
- Per image: 30 MB.
- Per run, all attachments together: 500 MB.
- Count: up to 30 images, shared with media URLs found in
input. - Idempotency: replaying a key with a different image list is
409 idempotency_conflict; a true replay does not re-fetch your images.
Where else does the same code appear?
The code is not specific to single runs. The Bulk runs page lists attachment_too_large among errors that fire while Sume resolves an item's attachments, before the queue is created, with the same status codes as a single call. The Agent Completions page lists the same 30 MB and 500 MB limits.
So a 413 on a bulk create means no queue exists and nothing was dispatched. Fix the offending item and resend the whole create.
How do I find the oversized file before sending?
Check sizes on your side. The script below flags files near the limits using a HEAD request; it only reads headers, and a server that omits content-length returns nothing, so treat a missing size as unknown rather than fine.
import asyncio
import httpx
PER_IMAGE = 30 * 1000 * 1000
PER_RUN = 500 * 1000 * 1000
async def main() -> None:
urls = ["https://cdn.example.com/shot.jpg", "https://cdn.example.com/pack.png"]
total = 0
async with httpx.AsyncClient(follow_redirects=True) as http:
for url in urls:
head = await http.head(url)
size = int(head.headers.get("content-length", "0"))
total += size
if size > PER_IMAGE:
print("over 30 MB:", url, size)
if total > PER_RUN:
print("set is over 500 MB:", total)
print("checked", len(urls), "images,", total, "bytes")
asyncio.run(main())What do the docs not say?
The Sume docs give 30 MB and 500 MB without saying whether a megabyte means 10^6 or 2^20 bytes, so leave margin instead of aiming at the line. They also do not say Sume will compress or resize an oversized image for you; the documented fix is to resize.
If the failure is a 502 attachment_fetch_failed instead, the problem is reachability, not size. That code points at an unreachable host, hotlink protection or a non-2xx answer, and details.index names the attachment.
Sources
Related posts
More in Developers
- Try Avatar 1.0 in the Sume playground before you write any code
Use the Sume Avatar playground to validate an avatar or avatar video payload, then move the same body into curl, the CLI or an agent without a rewrite.
- Bulk run: a bad item fails the whole create, a child failure does not
In a Sume bulk Format run, a bad item is a 400 with details.index and no queue; a child that fails admission after the 202 becomes one failed item.
- Canary 10% of video jobs to Sume before cutover: sticky bucketing
Moving video traffic off a shut-down API: hash a stable key into a percent bucket so each customer stays on one backend, and raise Sume's share in steps.
- Cancel a GPT Image 2.5 job: only possible before it starts
Sume's POST /v1/jobs/{id}/cancel works only before generation work starts. How to read cancelable, what the 409 means, and what a client timeout does not do.
Written by Sume