Reply auto-pauses sequence for that contact
Why it matters
Detecting a reply and not acting on it is worse than not detecting it at all — the system now has evidence that a human responded and chose to continue sending anyway. CWE-841 (Improper Enforcement of Behavioral Workflow) applies: the reply event is received but the workflow does not enforce the expected state transition (active → replied). Pending BullMQ or Sidekiq jobs scheduled before the reply are the specific failure vector: updating the enrollment status in the database does not cancel jobs already enqueued. The contact receives the next step at the scheduled time despite the status update, because the job handler may not re-check enrollment status before sending.
Severity rationale
High because detecting a reply without cancelling pending send jobs means the next scheduled step delivers regardless of enrollment status, continuing automated outreach after human engagement.
Remediation
In your handleReply function, update enrollment status and cancel pending jobs atomically — both actions must happen, not just the status write.
async function handleReply({ contactId, body }: ReplyEvent) {
// Update all active enrollments for this contact
await db.contactSequence.updateMany({
where: { contactId, status: { in: ['active', 'paused'] } },
data: { status: 'replied', repliedAt: new Date() }
})
// Cancel queued jobs — status update alone is not enough
const pendingJobs = await queue.getDelayed()
for (const job of pendingJobs) {
if (job.data.contactId === contactId) await job.remove()
}
// Notify the assigned rep
await notifyRepOfReply(contactId, body)
}
Also add a guard at the top of your send job handler: re-fetch enrollment status and return early if it is not 'active' — this covers the race window between status update and job execution.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Campaign Orchestration & Sequencing Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-841 — Improper Enforcement of Behavioral Workflow
- iso-25010:2011 · reliability.fault-tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from campaign-orchestration-sequencing·automated