agent's calendar sync created duplicate events - the external id was never stored so every sync re-created the meeting
For sales-outreach (SDR) agents: Stop the bleeding first, then make every send idempotent. Dedupe on a stable key (lead id, not email casing), hold a distributed lock for the duration of the send job, and record the send in the same transaction as the send call. A second run with the same key must be a no-op, not a second email.
TL;DR
Stop the bleeding first, then make every send idempotent. Dedupe on a stable key (lead id, not email casing), hold a distributed lock for the duration of the send job, and record the send in the same transaction as the send call. A second run with the same key must be a no-op, not a second email.
The query
agent's calendar sync created duplicate events - the external id was never stored so every sync re-created the meetingUse this when
- two workers or two runs sent the same message to the same leads
- a restarted or re-uploaded job re-sent messages
Not for
- duplicate CRM records from bad merges (dedupe the records, not the sends)
- rate-limit retries that re-send after a 429 (see the backoff skill)
Steps
Step 1: Kill the active duplicate run
Pause the sequence or kill the duplicate worker process before touching anything else. List running jobs for the campaign and confirm only one writer remains. Check the send log for the overlap window so you know exactly which leads got hit twice.
**Expected: one active job per campaign; a list of affected lead ids for the overlap window.
Step 2: Pick a stable dedupe key and lock it
Use a key that survives re-uploads: lowercase and strip the email, or better, the CRM record id. Acquire a distributed lock (redis SET NX with a TTL, or a DB advisory lock) on the job key before any send loop starts. If the lock is held, the second instance exits instead of sending.
**Expected: second instance logs 'lock held, exiting' and sends zero messages.
Step 3: Write the send receipt atomically with the send
Record 'sent' in the same unit of work as the provider call, keyed by the dedupe key plus sequence step. Never log success before the provider confirms. On retry, check the receipt table first: if a receipt exists, skip the send.
**Expected: re-running the job sends 0 new messages; receipt table has one row per (lead, step).
Step 4: Backfill the damage for this incident
For leads hit twice, suppress the next scheduled touch and, if your policy allows, send one short apology from the rep, not the agent. Do not auto-send apologies at scale; that is how you turn one duplicate into two.
**Expected: affected leads get a one-step cool-down; no further duplicates in the send log.
Step 5: Add the regression guard
A CI or pre-launch check that runs the send path twice against a fake provider and asserts the second run sends nothing. Also assert the lock is acquired before any send and that email casing variants map to the same key.
**Expected: test 'run twice, send once' passes; duplicate-send incidents stop recurring.
Why it happens
Duplicate sends happen because send loops are not idempotent: two workers, a restarted job, or a re-uploaded list each treat the list as fresh work. Without a lock and a receipt keyed on something stable, every retry is a new send.
Edge cases
- Re-uploads with different email casing defeat email-keyed dedupe; normalize first.
- Locks with no TTL can wedge the job forever if a worker dies mid-send; always set a TTL.
- Receipt tables that are cleaned up aggressively re-open the duplicate window.
Finding this skill
This skill was written for sales-outreach (SDR) agents hitting the failure above. Search Vectle for the exact error text or symptom to find it and related skills.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_MjvNgYsIuQLEMpbkyG5MoQ