Baseline and relation to #2678/#2680
Minimal reproduction
Call bulkWrite for multiple input rows with writeBatch returning each of:
- fewer records than inputs;
- extra records;
- records in reverse order;
- a non-array object.
All unsafe variants reproduced 2/2.
Expected / actual
- Expected: the batch boundary rejects or safely degrades responses that cannot prove one output per input in contract order.
- Actual:
records[i] is trusted without array/type/cardinality validation. Missing records become clean {ok:true, record:undefined}, extras are ignored, and reversed IDs are assigned to the wrong input rows.
Impact
The real import path confirmed downstream corruption: a short response reported a create with no ID; a reversed response mis-correlated IDs; async undo then left a created record permanently untracked.
Evidence and exclusions
- Source:
packages/core/src/utils/bulk-write.ts around the writeBatch success loop.
- Import consumers:
packages/rest/src/import-runner.ts result/undo mapping.
- An
undefined response throws and degrades safely; that subcase is not the bug.
- Generic correlation may require an explicit validator/key contract; at minimum array type and exact cardinality must be enforced before success.
Required regression tests
- Reject/degrade non-array, short, and long responses.
- Define and test correlation/order validation for returned records.
- Integration test that import result IDs and undo logs remain aligned with original rows.
Baseline and relation to #2678/#2680
98874656ffc50ce1531af52346228ffcdda73fba.bulkWritehelper (21420d9f82e); the helper is unchanged after merge.Minimal reproduction
Call
bulkWritefor multiple input rows withwriteBatchreturning each of:All unsafe variants reproduced 2/2.
Expected / actual
records[i]is trusted without array/type/cardinality validation. Missing records become clean{ok:true, record:undefined}, extras are ignored, and reversed IDs are assigned to the wrong input rows.Impact
The real import path confirmed downstream corruption: a short response reported a create with no ID; a reversed response mis-correlated IDs; async undo then left a created record permanently untracked.
Evidence and exclusions
packages/core/src/utils/bulk-write.tsaround thewriteBatchsuccess loop.packages/rest/src/import-runner.tsresult/undo mapping.undefinedresponse throws and degrades safely; that subcase is not the bug.Required regression tests