Fix Guide

How to Fix HubSpot Contact Merge Failures

Step-by-step fix guide with AI-powered diagnosis from BuildForce.

HubSpot contact merges fail when the two contacts have conflicting calculated properties (lifecycle stage that has progressed in one but regressed in the other), when one contact is the primary on a deal or company that the secondary can't inherit, when the secondary is referenced by an active workflow enrollment, or when API merge calls hit the wrong endpoint version. The fix is to inspect both contacts' associations and calculated properties, pick the primary contact deliberately (it inherits the secondary's history but keeps its own property values for non-blank fields), and use /crm/v3/objects/contacts/merge with the correct objectIdToMerge.

Primary Contact SelectionLifecycle Stage RulesWorkflow Enrollment BlockCalculated Property Conflict

Symptoms

Merge dialog showing 'Unable to merge — contacts cannot be combined' with no specific reason

POST /crm/v3/objects/contacts/merge returning 400 with 'OBJECT_NOT_FOUND' or 'INVALID_MERGE'

Lifecycle stage of the primary contact regressing after merge (e.g., Customer → Lead)

Custom calculated properties showing the wrong value post-merge

Associated deals or companies disappearing from one contact after the merge

Workflow re-enrolling the merged contact unexpectedly into a stale enrollment

Root Causes

1

Lifecycle stage cannot regress

HubSpot enforces a 'lifecycle stage can only move forward' rule. If contact A is at 'Customer' and contact B is at 'Lead', merging B into A keeps Customer — but merging A into B regresses to Lead and the platform blocks the merge unless you clear the stage on the primary first.

2

Active workflow enrollment on secondary

If the contact being merged into the primary is actively enrolled in a workflow with re-enrollment disabled, the merge fails because HubSpot can't transfer the enrollment cleanly. Unenroll from active workflows before merging.

3

Calculated property reconciliation conflict

Calculated properties (HubSpot score, custom calc properties) recompute post-merge based on the primary's data. If the secondary held the value that drove the calculation, the merged record's score can drop unexpectedly.

4

Primary email collision

When both contacts have a primary email (the canonical 'email' property), HubSpot keeps the primary contact's email and moves the secondary's email to the 'Additional emails' set. If your downstream integration only reads the primary email field, you lose addressability.

5

Wrong API endpoint or payload shape

The /crm/v3/objects/contacts/merge endpoint expects {primaryObjectId, objectIdToMerge}. Using the older /contacts/v1/contact/merge or swapping the IDs results in 400 errors or unintended primary selection.

How to Fix It — Step by Step

1

Identify both contacts' associations before merging

Pull both contacts with their associations to deals, companies, tickets, and engagements. The merge will move all associations to the primary, but you need to confirm there are no duplicates that will create stale links.

Example
GET /crm/v3/objects/contacts/{contactId}?associations=deals,companies,tickets&properties=email,lifecyclestage,hs_lead_status
2

Pick the primary contact deliberately

The primary contact's property values win for any field where both contacts have a non-blank value. Pick as primary the contact with: the most recent activity, the further-progressed lifecycle stage, and the canonical email you want to keep as the main address.

3

Unenroll from active workflows on the secondary

Before calling merge, remove the secondary contact from any active workflow enrollments. Use POST /automation/v2/workflows/{workflowId}/enrollments/contacts/{contactId}/unenroll for each blocking workflow. This is the single most common cause of merge 400s.

4

Clear conflicting lifecycle stage on the primary if needed

If the primary needs to take on the secondary's stage (rare — you should usually pick the more-advanced contact as primary), clear the primary's lifecycle stage before merging. HubSpot will then accept the secondary's value during the merge.

Example
PATCH /crm/v3/objects/contacts/{primaryId}
{
  "properties": { "lifecyclestage": "" }
}
5

Call the v3 merge endpoint with correct payload

Issue the merge via the v3 endpoint with primaryObjectId and objectIdToMerge. The objectIdToMerge contact will be archived (not deleted) and accessible via GET with archived=true for 90 days.

Example
POST /crm/v3/objects/contacts/merge
{
  "primaryObjectId": 123,
  "objectIdToMerge": 456
}
6

Verify post-merge property values and associations

Fetch the merged primary contact and audit: primary email, lifecycle stage, custom calculated properties, and association counts. Compare against the pre-merge snapshot to confirm nothing dropped unexpectedly.

7

Configure prevention: deduplication tool + integration upsert keys

Run the HubSpot Duplicates tool weekly. In every integration writing to HubSpot, set the matching key to email (or a custom unique-ID property) so new records upsert against existing contacts instead of creating duplicates that need merging later.

Let BuildForce diagnose and fix this automatically

Instead of following manual steps, connect your org and let our AI identify exactly what's broken and how to fix it — in minutes.

Book a Demo

Common Questions

More answers about this issue and how to resolve it.

Stop debugging manually. Let AI do it.

BuildForce runs 200+ automated checks across your Salesforce org and tells you exactly what's broken and how to fix it.