A transient provider error during the analyze chain (e.g. transcription HTTP 503/429/timeout) permanently fails the replay despite the queue being configured with 3 retries.
Flow: the stage processor catches the error and calls markReplayFailed(...), flipping lifecycle_state to failed (src/server/replays/replays.service.ts:382), then re-throws. bunqueue schedules a retry; on re-run the processor's lifecycle guard sees the row is no longer analyzing and early-exits returning {ok:true} (src/server/jobs/analyze-replay/analyze-replay.processor.ts:98-100,146-156). bunqueue marks the job completed. The retry never re-attempts the work.
Net effect: retry.maxAttempts: 3 (src/server/jobs/jobs.bunqueue.ts:50-51) is dead for every stage failure — a single transient blip on one turn's transcription is terminal.
Confirmed live: a replay that hit a transcription 503 stayed failed; only a fresh replay succeeded.
A transient provider error during the analyze chain (e.g. transcription
HTTP 503/429/timeout) permanently fails the replay despite the queue being configured with 3 retries.Flow: the stage processor catches the error and calls
markReplayFailed(...), flippinglifecycle_statetofailed(src/server/replays/replays.service.ts:382), then re-throws. bunqueue schedules a retry; on re-run the processor's lifecycle guard sees the row is no longeranalyzingand early-exits returning{ok:true}(src/server/jobs/analyze-replay/analyze-replay.processor.ts:98-100,146-156). bunqueue marks the jobcompleted. The retry never re-attempts the work.Net effect:
retry.maxAttempts: 3(src/server/jobs/jobs.bunqueue.ts:50-51) is dead for every stage failure — a single transient blip on one turn's transcription is terminal.Confirmed live: a replay that hit a transcription
503stayedfailed; only a fresh replay succeeded.