How to merge duplicate leads in Salesforce without waking the wrong automation
When a team says "just merge the duplicate leads," what they usually mean is: do not break Lead Status, do not convert the wrong rows, and do not create a cleanup run that nobody can explain later. Safe lead dedupe starts with reviewable clusters, not with a bulk merge button.
Run preflight first
Check converted LeadStatus values, duplicate rules, and anonymous Apex support before you even think about applying mixed Lead and Contact clusters.
Cluster the duplicates offline
Use enterprise-plan to group Leads and Contacts into reviewable clusters instead of merging individual rows by feel.
Review every mixed cluster
A Lead-to-Contact conversion is only auto-translatable when the cluster is exactly one Lead plus one Contact. Larger mixed clusters should stay manual.
Dry-run before --apply
The Salesforce merge-apply-plan command is dry-run by default, so preview the operation mix and skipped clusters before you execute.
The exact safety loop for leads
First, preflight the org. The code checks whether the org can execute lead conversions cleanly, whether a converted LeadStatus value exists, and whether duplicate rules or Apex constraints are likely to interfere.
Second, plan the run with g-gremlin dedup enterprise-plan. That gives you clusters, review notes, and a cluster-level review queue you can hand to RevOps.
Third, dry-run g-gremlin sfdc merge-apply-plan. The command tells you how many merge operations and convertLead operations would run and how many clusters were skipped because they still need manual review.
Only then do you pass --apply. That is where receipt files, state files, retries, and verify checks matter.
Not every mixed cluster should convert automatically
Dry-run first
Preview the operation mix before anything mutates.
g-gremlin sfdc merge-apply-plan \
--plan plan.json \
--approval-file review_clusters.csv \
--receipt-file receipt.jsonApply approved lead work
Add converted status when approved mixed clusters will execute as lead conversions.
g-gremlin sfdc merge-apply-plan \
--plan plan.json \
--approval-file review_clusters.csv \
--receipt-file receipt.json \
--state-file state.json \
--converted-status "Qualified" \
--applyReceipt-backed apply
The receipt stores the command name, plan path, plan digest, and approval-file digest when approvals are used.
dry_run, resume, org alias, and optional state-file path.
All skipped, succeeded, and failed operations are serialized into the receipt payload.
Verification is separate: merge verify checks master/victim state, and convert-lead verify checks converted status and resulting records.
The buyer-language takeaway
Do not merge duplicate leads from a spreadsheet without a review queue.
Do not trust a mixed Lead and Contact cluster unless a human approved it.
Do not run live apply before you know what Lead Status and conversion will trigger.
Do use dry-run, receipts, and verify so the team can defend what happened afterward.
Continue in the cluster
Salesforce dedupe guide
The audit-first pillar: blocking-first planning, cluster review, supervised merge, receipts, and where native duplicate rules fall short.
Why Salesforce duplicate rules do not work
Rule-based matching, duplicate-record-set limits, and why alert-or-block is not the same as reviewable clustering.
Fix duplicate accounts in Salesforce
A candid page on account duplicate cleanup, what native rules do, and where the public Gremlin workflow stops today.
Audit duplicates before merging in Salesforce
What to inspect before a merge run: blocking anchors, review queues, approvals, dry-runs, and receipts.
Salesforce lead-status audit
Lead dedupe often wakes routing and status logic, so check what Lead Status actually controls before live merges.
FAQ
What makes Salesforce lead dedupe risky?
Lead dedupe is risky because merges can touch conversion logic, Lead Status, assignment behavior, and downstream routing. The data problem is only half the job. The other half is understanding what your org will do when those rows change state.
How does Gremlin handle duplicate Lead and Contact pairs?
If a reviewed mixed cluster is exactly one Lead plus one Contact, the apply layer can translate that into a convertLead operation. If the mixed cluster is more complex than that, the workflow skips it with a manual-resolution reason instead of guessing.
Do I need a converted status value?
Yes, for live convertLead operations. If approved mixed clusters are going to execute as lead conversions, the apply command needs --converted-status. Dry-run can still show you the operation mix before live execution.
Keep the conversation going
These pages are meant to help operators solve real problems. If you want the next guide, grab the low-friction option. If you need the implementation, not just the guide, book time.
Get the next guide when it ships
I publish architecture guides grounded in real implementations. No generic AI filler.
Use your work email so I can keep the list useful and relevant.
Need the implementation, not just the guide?
Book a 15-minute working session with Mike right on his calendar. Tooling, consulting, or a mix of both is fine.
Open Mike's calendarIf you want me to come in with context, leave your email and a short note before the call.