One dead image URL fails the whole 100-item Sume bulk create
Sume fetches every attachment at create time, so one broken image URL in a bulk body fails the create before any queue exists. Check URLs first.

If one item in a 100-item bulk body has an attachment URL that Sume cannot fetch, the whole create fails and no queue is made. The API resolves every item's attachments before it creates the queue, so the failure shows up in seconds instead of minutes into a run.
Why it fails early
For a single run, Sume fetches each attachment at create, checks its real type and size, and copies it into durable storage. A broken or private image fails the create with a 4xx or 5xx you can act on, rather than stopping the run later. Bulk keeps that rule: the attachment codes are returned before the queue is created.
| Code | Status | Usual cause |
|---|---|---|
| invalid_attachment | 400 | Wrong type or shape, or more than 30 images on an item |
| attachment_not_found | 400 | asset_id unknown or not ready, or in another workspace |
| attachment_too_large | 413 | Image over 30 MB |
| attachment_fetch_failed | 502 | Public URL that needs auth or no longer resolves |
A pre-flight that costs nothing
Image types are JPEG, PNG, WebP, GIF and AVIF, up to 30 images and 30 MB each per run. Before you build the bulk body, check each URL yourself.
- Send a HEAD or a ranged GET from your own server with no credentials, since Sume fetches without auth.
- Drop or repair rows that fail, and keep a map from item index to SKU so you can report which row was dropped.
- Re-create with a new
Idempotency-Keyif you changed the body; the same key with a different payload is409 idempotency_conflict.
Reading the failure
The error names the problem, not always the item, so keep the bulk body you sent and bisect if the response does not point at a row. Because nothing was dispatched, a retry after you fix the URL is clean: no children exist and nothing was charged.
If you send a changed body, give it a new Idempotency-Key. The same key with a different payload returns 409 idempotency_conflict and names the original queue in details.queue_id, which is only useful when a queue was created in the first place.
A practical habit is to store each product image on a host you control, so the URL cannot go stale between your pipeline run and the queue create. Check every URL before you send the body, because one bad item stops the whole create before any queue exists.
Tradeoff
Failing the whole create is strict, but it means a bad image never costs you a generation. The cost is that one stale CDN link can block 99 good rows until you remove it. A pre-flight pass is cheaper than finding out from a 502.
Sources
Related posts
More in Formats
- Commit several Sume Format files in one PUT: a change set
PUT a files list to a Sume Format's contents URL and it is one commit with one version bump. Files you do not name stay as they are. Existing paths need a sha.
- Create a Sume Format over the API: auto_init and the first package sha
POST /v1/formats with auto_init (default true) commits a minimal SKILL.md and returns package_sha, contents_url and vanity_invoke_url. Keep all three.
- enum and const in a Sume output schema: a status that cannot drift
Use enum and const in a Sume output_schema to pin a status field to values your publisher expects, since oneOf and allOf are rejected. Examples that pass.
- A failed Format run webhook still has the receipt: salvage artifacts
When a Sume Format run fails, the webhook has status ERROR but payload is still the full receipt, with artifacts and output_error. Read them before you retry.
Written by Sume