Severity
Critical — the automatic REST→Bulk switch at 2,000 rows changes write semantics and loses data.
What happens
recordsToCsv takes headers from Object.keys(records[0]) only. mapRecords omits a key when a cell is blank with "ignore blank" behavior — so if record 0 has a blank Phone, the CSV has no Phone column at all and every other row's Phone value is silently never uploaded.
- "Clear field" maps blanks to
null, serialized as '' — but Bulk API 2.0 ignores empty values on update and requires #N/A to null a field. Blank-means-clear silently no-ops on the Bulk path while the identical mapping clears correctly via REST JSON null.
Evidence
src/services/salesforce/bulk-api.ts:277 (headers from first record; null → '')
src/data/mappers/index.ts:127-130 (blank-ignore omits keys)
- Routing:
src/background/index.ts:1661
Suggested fix
Build the header row as the union of keys across all records, emit #N/A for explicit nulls, and quote \r.
Environment
Commit 74cf21b (main), WaveLink 0.6.0. Found in the 2026-08-31 adversarial audit (code-verified).
Severity
Critical — the automatic REST→Bulk switch at 2,000 rows changes write semantics and loses data.
What happens
recordsToCsvtakes headers fromObject.keys(records[0])only.mapRecordsomits a key when a cell is blank with "ignore blank" behavior — so if record 0 has a blank Phone, the CSV has no Phone column at all and every other row's Phone value is silently never uploaded.null, serialized as''— but Bulk API 2.0 ignores empty values on update and requires#N/Ato null a field. Blank-means-clear silently no-ops on the Bulk path while the identical mapping clears correctly via REST JSONnull.Evidence
src/services/salesforce/bulk-api.ts:277(headers from first record; null → '')src/data/mappers/index.ts:127-130(blank-ignore omits keys)src/background/index.ts:1661Suggested fix
Build the header row as the union of keys across all records, emit
#N/Afor explicit nulls, and quote\r.Environment
Commit
74cf21b(main), WaveLink 0.6.0. Found in the 2026-08-31 adversarial audit (code-verified).