A job payload containing only {to, subject, html} becomes useless the moment it lands in the DLQ. Without a campaign ID, a recipient ID, and a correlation key, you cannot answer which campaign generated the failure, which contact never received the message, or whether the failure was isolated or systemic. ISO-25010:2011 maintainability.analysability requires that system faults can be diagnosed from the available artifacts — an untraceable job payload defeats that entirely, forcing triage through raw log searches across worker instances.
High because untraceable failed jobs in a DLQ cannot be attributed, replayed selectively, or used to satisfy delivery audit requirements without manual cross-referencing of logs.
Include all three traceability fields at the point of enqueue in lib/queue.ts or wherever campaign sends are dispatched:
await emailQueue.add('send', {
campaignId: campaign.id,
recipientId: contact.id,
correlationId: `${campaign.id}:${contact.id}`,
templateId: template.id,
to: contact.email,
mergeFields: { firstName: contact.firstName }
})
In the worker, log all three fields on both success and failure paths so correlation IDs appear in structured log queries.
ID: sending-pipeline-infrastructure.queue-architecture.job-traceability
Severity: high
What to look for: Enumerate all required traceability fields in the job payload: (1) campaign/template ID, (2) recipient ID or email, (3) correlation ID or composite key. Count how many of these 3 fields are present in the job payload structure. Also check that the worker logs include these fields on both success and failure paths.
Pass criteria: Every email job payload includes all 3 traceability fields: a campaign/template identifier, a recipient identifier, and either a correlation ID or a composite key (campaign + recipient) that uniquely identifies the send attempt. These fields are logged by the worker on both success and failure. Report even on pass: list the 3 traceability fields found and their locations.
Fail criteria: Job payloads contain only the bare minimum (email address and body) with no campaign identifier. Failed jobs in the DLQ cannot be attributed to a specific campaign. Worker logs do not include campaign or recipient IDs. Or fewer than 3 traceability fields are present.
Skip (N/A) when: The application sends only single one-off emails with no campaigns, sequences, or batch sends — confirmed by the absence of campaign models.
Detail on fail: "Job payload only contains {to, subject, html} — no campaign_id or recipient_id. DLQ jobs untraceable" or "Worker logs email address only — no campaign context in error logs"
Remediation: Include traceability fields in every job payload:
// When enqueuing
await emailQueue.add('send', {
campaignId: campaign.id,
recipientId: contact.id,
correlationId: `${campaign.id}:${contact.id}`,
templateId: template.id,
to: contact.email,
mergeFields: { ... }
})
// In worker — log with context
logger.info({ campaignId, recipientId, correlationId }, 'Email sent successfully')
logger.error({ campaignId, recipientId, correlationId, error }, 'Email send failed')
For queue depth monitoring and alerting, see the Operational Resilience (Email) Audit which covers queue observability in detail.