Issue summary
When using a cross-object reference field as externalId (e.g. "Account__r.Name"), SFDMU v5 fails to match source CSV records against existing target org records during csvfile->org import. All records are silently classified as inserts - no error or warning is raised - even though the target org contains matching records and the Account__r.Name column is present in the CSV with correct values.
Additionally, the exported CSV contains no dedicated composite external ID column (the $$... column present in v4 exports). Only the constituent reference fields (e.g. Account__r.Name) appear as separate columns.
This worked correctly in v4.39.0 and below.
Steps to reproduce
export.json:
{
"objectSets": [{
"objects": [
{
"master": true,
"externalId": "Name",
"query": "SELECT Id, Name FROM Account WHERE Name IN ('Acme Corp')",
"operation": "Readonly"
},
{
"master": false,
"externalId": "Account__r.Name",
"query": "SELECT Id, Account__c FROM TestAccount__c",
"operation": "Upsert"
}
]
}]
}
Step 1 - org->csv:
sf sfdmu run --sourceusername source@org.com --targetusername csvfile --path ./data/ --diagnostic --anonymise
Step 2 - csvfile->org:
sf sfdmu run --sourceusername csvfile --targetusername target@org.com --path ./data/ --diagnostic --anonymise --simulation
Expected behavior
Records matched by Account__r.Name and classified as updates:
[diagnostic] update classified: toInsert=0 toUpdate=N nonProcessed=0
Actual behavior
Setup, validation, and data retrieval complete without error. SFDMU correctly recognises and expands the external ID in the query. Despite matching records existing in the target org, all records are classified as inserts:
[diagnostic] update classified: toInsert=N toUpdate=0 nonProcessed=0
2026-03-26__08_02_12.log
2026-03-26__08_02_18.log
With --simulation removed, this would cause duplicate insert attempts against a live org with no warning.
Related issues
Log file (required)
Two logs attached covering the full round-trip:
My best guess for root cause: When SFDMU v5 fetches target org records, jsforce returns relationship fields as nested objects ({ Account__r: { Name: "Acme Corp" } }). The v4 engine had a ___parseRecords step in sfdx.ts that flattened these to record["Account__r.Name"] = "Acme Corp" before matching. That step was removed in v5 (OrgDataService.ts). As a result, looking up record["Account__r.Name"] on any target org record returns undefined, every target record's external ID key is undefined, and no source record matches -> everything is an insert.
Issue summary
When using a cross-object reference field as externalId (e.g. "Account__r.Name"), SFDMU v5 fails to match source CSV records against existing target org records during csvfile->org import. All records are silently classified as inserts - no error or warning is raised - even though the target org contains matching records and the Account__r.Name column is present in the CSV with correct values.
Additionally, the exported CSV contains no dedicated composite external ID column (the $$... column present in v4 exports). Only the constituent reference fields (e.g. Account__r.Name) appear as separate columns.
This worked correctly in v4.39.0 and below.
Steps to reproduce
export.json:
Step 1 - org->csv:
sf sfdmu run --sourceusername source@org.com --targetusername csvfile --path ./data/ --diagnostic --anonymiseStep 2 - csvfile->org:
sf sfdmu run --sourceusername csvfile --targetusername target@org.com --path ./data/ --diagnostic --anonymise --simulationExpected behavior
Records matched by
Account__r.Nameand classified as updates:[diagnostic] update classified: toInsert=0 toUpdate=N nonProcessed=0Actual behavior
Setup, validation, and data retrieval complete without error. SFDMU correctly recognises and expands the external ID in the query. Despite matching records existing in the target org, all records are classified as inserts:
[diagnostic] update classified: toInsert=N toUpdate=0 nonProcessed=02026-03-26__08_02_12.log
2026-03-26__08_02_18.log
With
--simulationremoved, this would cause duplicate insert attempts against a live org with no warning.Related issues
Log file (required)
Two logs attached covering the full round-trip:
My best guess for root cause: When SFDMU v5 fetches target org records, jsforce returns relationship fields as nested objects
({ Account__r: { Name: "Acme Corp" } }). The v4 engine had a___parseRecordsstep in sfdx.ts that flattened these torecord["Account__r.Name"] = "Acme Corp"before matching. That step was removed in v5 (OrgDataService.ts). As a result, looking uprecord["Account__r.Name"]on any target org record returns undefined, every target record's external ID key is undefined, and no source record matches -> everything is an insert.