Sume public_reason: generation_rejected vs temporary error
How Sume picks generation_rejected, temporary_generation_error or generation_failed on a failed job from the provider HTTP status and the retryable flag.

On a failed generation job, Sume derives public_reason from the provider's HTTP status and the retryable flag. A 4xx gives generation_rejected, a retryable failure gives temporary_generation_error, and generation_failed is the leftover for a 5xx that the worker marked not retryable.
This applies to the stored codes provider_execution_failed and generation_failed, after the typed reasons have had their turn. The logic is in packages/api-jobs/src/public-job.ts.
The five default outcomes
Sume reads the status from details.status, details.status_code or provider_http_status. A stored retryable boolean wins; when it is missing, the default is retryable for a 5xx and not retryable for a 4xx. These rows assume that default.
The stage on these rows is generation_processing unless the worker named a more specific stage. retry_after_seconds is filled only for retryable rows, rounded up and capped at 300.
| Provider status | category | public_reason | retryable | next_action |
|---|---|---|---|---|
| 4xx | generation_rejected | generation_rejected | false | inspect_events |
| 5xx | generation_unavailable | temporary_generation_error | true | retry_later |
| 5xx, stored retryable false | generation_unavailable | generation_failed | false | inspect_events |
| None, stored retryable true | generation_timeout | temporary_generation_error | true | retry_later |
| None, stored retryable false | generation_rejected | generation_rejected | false | inspect_events |
Typed reasons that win first
Before the defaults apply, the remap checks for failures it can name precisely. Any of these replaces the generic label and usually changes next_action to fix_input.
- An artifact the storage refused as too large, covered in the artifact_too_large guide.
- An input URL the provider could not download, which becomes
input_media_unreachable. - A negative prompt sent to a model that does not take one.
- Content-policy wording in the provider text, which becomes
content_policy_rejected. - A failure at an image-input stage, which becomes
image_content_rejectedwhen it is not retryable.
Why a 4xx is not retried for you
A 4xx from the provider says the request itself was refused, so repeating the same body repeats the refusal. That is why generation_rejected is not retryable and points to inspect_events: the events and details.provider_error_message hold the reason, and the fix is in the request. A 5xx or a missing status says the provider or the worker stumbled, so waiting and trying again is reasonable.
A small decision function
A client can branch on the three public fields and ignore the rest. This function runs as written.
For the category names around these reasons, see the job error categories.
def decide(error):
if not error.get("retryable"):
if error.get("next_action") == "fix_input":
return "fix the request"
return "read events, then stop"
wait = min(error.get("retry_after_seconds") or 30, 300)
return "wait %s seconds, submit again" % wait
print(decide({"public_reason": "generation_rejected", "retryable": False,
"next_action": "inspect_events"}))
print(decide({"public_reason": "temporary_generation_error", "retryable": True,
"next_action": "retry_later", "retry_after_seconds": 20}))Sources
Related posts
More in Developers
- Sume "Generation could not start": rejected request or outage
Generation could not start is the fallback when a provider rejects a submit. A 4xx gives generation_rejected_request; anything else gives submit_failed.
- Sume job error details.input_field: the parameter that failed
When a provider rejects one request field, Sume publishes its name as details.input_field beside provider_error_message. Map it back to your body and fix it.
- Sume job failed artifact_too_large: shrink the output
A finished file that storage refuses with HTTP 413 fails as artifact_too_large and is not retryable. Shorten the cut, lower the resolution or the bitrate.
- Sume content_policy_rejected: image, music and video messages
Sume scans a provider's rejection text for six phrases and answers with one of three fixed content-policy messages and next_action fix_input.
Written by Sume