Dispatch failures set error.retryable to true
Read error.retryable as true when a job failed because dispatch ran out of retries or a runner was decommissioned. Five codes were misclassified.
A failed job comes back with an error object, and error.retryable answers the only question that matters at that moment: is it worth submitting the same request again? For a set of infrastructure failures it answered no when the honest answer was yes.
The classifier listed one dispatch code, DISPATCH_ERROR, that nothing on the platform writes any more. The codes it does write were all missing from it:
DISPATCH_EXHAUSTED, when the dispatch queue used up every retryDISPATCH_UNAVAILABLE, when a job could not reach a runner in timePROVIDER_CLEARED, when a runner was decommissioned mid-flightP1_EXECUTION_ERROR, when an inline job died with the worker running it
All five now report retryable: true, on GET /jobs/:id, on the job.failed webhook, and through the SDK. Nothing about the response shape changed, so clients already reading the field pick this up with no code change.
{ "error": { "code": "DISPATCH_EXHAUSTED", "message": "Job dispatch failed after all queue retries. The dispatch queue could not deliver to any provider.", "retryable": true }}Real failures still read false. A rejected input, an ffmpeg error, a job that ran past your plan’s time budget, and a permanent dispatch defect (DISPATCH_FAILED) all replay the same outcome on a retry, so they stay terminal. Every code is listed in the error reference, and the messages that go with them were rewritten in clearer errors when a job times out.
