Inngest NonRetriableError and RetryAfterError for Sume errors
Map Sume HTTP errors to Inngest: NonRetriableError for 400, 401, 402 and 404, and RetryAfterError with the retry-after header on a 429.

Throw NonRetriableError for Sume errors that cannot succeed on a retry, and RetryAfterError with the delay from the retry-after header when Sume returns a 429. Anything else can use Inngest's default retries.
Inngest facts are from its error-handling and errors reference docs and the v1.45.0 release; Sume facts from Errors and credits and Authentication, read 2026-10-01.
What do the two classes do?
Per the docs, NonRetriableError stops retries, and RetryAfterError controls retry timing. Its second argument accepts milliseconds as a number, a string such as "30m", or a Date. Inngest v1.45.0, released September 17, also made API v2 return 400 for unsupported query parameters or bodies; that is separate from your function errors.
Which Sume status maps to which class?
Sume's error envelope has error.code, message, request_id and details. A 429 names error.details.scope as read or write and sends retry-after.
| Sume status and code | Inngest throw |
|---|---|
400 invalid_request | NonRetriableError |
401 unauthorized | NonRetriableError |
402 insufficient_credits | NonRetriableError |
404 not_found | NonRetriableError |
409 idempotency_conflict on submit | NonRetriableError |
429 rate_limited | RetryAfterError using retry-after |
429 queue_full, 503 provider_capacity_exceeded | Default retry or a longer RetryAfterError |
How do you write the mapping?
One helper takes the SDK's response and error and throws the right class. The fallback of 30 seconds for a missing header is my choice, not a Sume value.
import { NonRetriableError, RetryAfterError } from "inngest";
export function raiseForSume(response: Response, error: unknown): void {
const status = response.status;
if (status === 429) {
const seconds = Number(response.headers.get("retry-after"));
const ms = Number.isFinite(seconds) && seconds > 0 ? seconds * 1000 : 30000;
throw new RetryAfterError("sume rate limited", ms);
}
if ([400, 401, 402, 404, 409].includes(status)) {
throw new NonRetriableError("sume " + status + ": " + JSON.stringify(error));
}
if (status >= 400) throw new Error("sume " + status);
}What about Formats and job errors with retryable?
Format and job errors also carry retryable, retry_after_seconds and next_action. Prefer those fields when present, and fall back to the status mapping above. See the error fields post.
Sources
Related posts
More in Developers
- Instagram API 100 posts per 24 hours: size your bulk queue
Instagram limits API-published posts to 100 in a moving 24-hour period, checked at content_publishing_limit. A Sume bulk queue also tops out at 100 items.
- Instagram API error: Maximum number of sponsors exceeded (2)
Instagram's publishing error table lists 'Maximum number of sponsors exceeded. Limit is 2 per post.' and 'Cannot tag yourself as sponsor.' How to prevent both.
- Edits 15-minute export vs Sume's 900-second trim and detach cap
Edits now exports up to 15 minutes on iOS. Sume trim and audio detach also top out at 900 seconds of output, from a source up to 1800 seconds.
- Edits compare 3 reels: read the clips with Sume video inspect
Instagram Edits compares up to 3 reels by views and watch time. Sume video inspect adds what the clips contain: probe facts, stills and an optional transcript.
Written by Sume