Background queues have a dead-letter or error-handling path
Why it matters
Background job queues without a dead-letter path are silent failure sinks: a job that consistently fails disappears from the active queue after its retry cap is exhausted, leaving no record of what went wrong unless you explicitly configure failure handling. For payment-adjacent jobs — subscription renewals, fulfillment triggers, invoice generation — silent failure means lost revenue and customer confusion. Even for non-financial jobs, the absence of a failure path makes debugging a production incident nearly impossible: you know something is wrong because users report it, but the queue gives you no evidence. The observability gap is the core risk, not the job failure itself.
Severity rationale
Low because a missing dead-letter path does not cause immediate harm but compounds debugging difficulty and hides systematic failures until user-reported impact escalates.
Remediation
Add a failed event handler to every Worker and route failures to your alerting stack. In src/lib/worker.ts or wherever workers are initialized:
import * as Sentry from '@sentry/node'
const worker = new Worker('payments', async (job) => {
// ... job processor
})
worker.on('failed', (job, err) => {
console.error(`[queue] Job ${job?.id} (${job?.name}) failed after ${job?.attemptsMade} attempts:`, err)
Sentry.captureException(err, { extra: { jobId: job?.id, jobName: job?.name } })
})
worker.on('error', (err) => {
Sentry.captureException(err)
})
Set removeOnFail: { count: 500 } to keep the last 500 failed jobs in Redis for post-mortem inspection without unbounded storage growth.
Detection
-
ID:
queue-deadletter-configured -
Severity:
low -
What to look for: When a background job library is in dependencies, walk source files for queue/worker setup calls:
new Queue(,new Worker(,inngest.createFunction(,client.publish(. Count all queue setups and verify each has an error-handling configuration: afailedevent handler (worker.on('failed', ...)), aremoveOnFailoption set, adeadLetterQueueconfig, aninngestonFailurehandler, OR a try/catch around the job processor that logs/alerts. -
Pass criteria: 100% of queue setups have error-handling configured. Report: "X queue setups inspected, Y with error handling, 0 silent-failure."
-
Fail criteria: At least 1 queue setup has no error-handling path.
-
Skip (N/A) when: No background job library in dependencies.
-
Detail on fail:
"1 silent-failure queue: src/lib/worker.ts new Worker('payments', processor) has no .on('failed', ...) listener — failed jobs disappear with no log" -
Remediation: Without error handling, failed jobs vanish silently — you only find out when customers complain. Add a failure listener:
// Bad: failures are silent const worker = new Worker('payments', async (job) => { ... }) // Good: log and alert on failure worker.on('failed', (job, err) => { console.error(`Job ${job.id} failed:`, err) // ... send to Sentry, etc. })
External references
- iso-25010:2011 · reliability
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ai-slop-cost-bombs·automated