{"record":{"id":"e70170a27a1be6d3","repo":"chroma-core/chroma","slug":"transaction-already-has-a-buffered-write-for-id-e70170","errorCode":null,"errorMessage":"transaction already has a buffered write for id \"{id}\"","messagePattern":"transaction already has a buffered write for id \"(.+?)\"","errorType":"exception","errorClass":"InvalidArgumentError","httpStatus":400,"severity":"error","filePath":"chromadb/api/conditional_http.py","lineNumber":292,"sourceCode":"        operation: str,\n        ids: IDs,\n        payload: ConditionalHttpJsonPayload,\n    ) -> None:\n        self._validate_buffered_write(operation, ids)\n        for id in ids:\n            self._buffered_write_ids.add(id)\n        self._operations.append({\"operation\": operation, \"payload\": payload})\n\n    def _validate_buffered_write(self, operation: str, ids: IDs) -> None:\n        call_ids: Set[str] = set()\n        for id in ids:\n            if id in call_ids:\n                raise InvalidArgumentError(\n                    f'transactional write request contains duplicate id \"{id}\"'\n                )\n            call_ids.add(id)\n            if id in self._buffered_write_ids:\n                raise InvalidArgumentError(\n                    f'transaction already has a buffered write for id \"{id}\"'\n                )\n            self._validate_write_precondition(operation, id)\n\n    def _validate_write_precondition(self, operation: str, id: str) -> None:\n        if operation == \"add\" and id not in self._known_absent:\n            raise InvalidArgumentError(\n                f'transactional add for id \"{id}\" requires a prior read '\n                \"proving the id is absent\"\n            )\n        if operation == \"update\" and id not in self._known_present:\n            raise InvalidArgumentError(\n                f'transactional update for id \"{id}\" requires a prior read '\n                \"proving the id is present\"\n            )\n        if operation == \"delete\" and id not in self._known_present:\n            raise InvalidArgumentError(\n                f'transactional delete for id \"{id}\" requires a prior read '","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/conditional_http.py#L274-L310","documentation":"Raised by _validate_buffered_write (chromadb/api/conditional_http.py:292) when an id is buffered for write a second time by a later call within the same transaction. Unlike the per-call duplicate check, this spans the whole transaction via _buffered_write_ids: once a write for an id is pending, any further write to that id (even in a separate call) is rejected, because the commit applies buffered operations in order and a second payload would make the final state ambiguous against the OCC read set.","triggerScenarios":"Two transactional writes touching the same id in one transaction: collection.update(ids=[\"a\"], ...) followed later by collection.delete(ids=[\"a\"], ...), or two add/upsert calls sharing an id across different code paths inside one transaction block.","commonSituations":"A retry loop inside the transaction that re-buffers a failed write; helper functions each doing their own upsert for the same record, composed in one transaction; processing a list where logic updates a record, then a later branch deletes it.","solutions":["Restructure so each id is written exactly once per transaction: decide the final operation (add, update, upsert, or delete) before buffering it","Batch same-id writes into a single call with the final payload (upsert is usually what you want)","Track written ids client-side in a set as you go and skip or consolidate repeats"],"exampleFix":"# before\nwith client.transaction():\n    collection.update(ids=[\"a\"], metadatas=[{\"v\": 1}])\n    collection.delete(ids=[\"a\"])            # same id buffered twice\n# after\nwith client.transaction():\n    collection.delete(ids=[\"a\"])            # single final operation for \"a\"","handlingStrategy":"validation","validationCode":"written = set()\n\ndef txn_write_once(ids):\n    dupes = written.intersection(ids)\n    if dupes:\n        raise RuntimeError(f\"ids already buffered in this transaction: {sorted(dupes)}\")\n    written.update(ids)\n    return ids","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track every id you have written in the current transaction in a client-side set","Consolidate same-id writes into one final operation before buffering","Do not retry a buffered write inside the same transaction; abort and start a new one"],"tags":["chromadb","transaction","write-buffer","duplicate-ids","occ"],"backgroundTag":"transaction-validation-failed","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}