{"record":{"id":"53425dae409a8982","repo":"chroma-core/chroma","slug":"txn-commit-cannot-be-called-inside-run-53425d","errorCode":null,"errorMessage":"txn.commit() cannot be called inside run()","messagePattern":"txn\\.commit\\(\\) cannot be called inside run\\(\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/models/ConditionalCollectionTransaction.py","lineNumber":274,"sourceCode":"        delete_request = self._collection._validate_and_prepare_delete_request(\n            ids, None, None\n        )\n        if delete_request[\"ids\"] is None:\n            raise ValueError(\"ids must be provided for transactional delete\")\n\n        self._run_transaction_operation(\n            lambda: self._collection._client._conditional_delete(\n                transaction=self._transaction,\n                collection_id=self._collection.id,\n                ids=delete_request[\"ids\"],\n                tenant=self._collection.tenant,\n                database=self._collection.database,\n            )\n        )\n\n    def commit(self) -> ConditionalCommitResult:\n        if self._commit_blocked_by_run:\n            raise ValueError(\"txn.commit() cannot be called inside run()\")\n        return self._commit_after_run()\n","sourceCodeStart":256,"sourceCodeEnd":276,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/models/ConditionalCollectionTransaction.py#L256-L276","documentation":"Chroma's ConditionalCollectionTransaction.run(callback) owns the commit lifecycle: while the callback executes it sets an internal flag (_commit_blocked_by_run, chromadb/api/models/ConditionalCollectionTransaction.py:59) and after the callback returns it commits itself, retrying with a fresh transaction on ConditionalWriteConflictError/StaleReadError/BackoffError. txn.commit() raises this ValueError when invoked inside that callback, because a manual commit would double-commit buffered writes and defeat run()'s retry semantics.","triggerScenarios":"Calling t.commit() on the transaction handle passed into the run() callback, e.g. txn.run(lambda t: (t.add(ids=['a'], embeddings=[[0.1]]), t.commit())) or a named callback whose last line is t.commit(). commit() is only legal on a transaction used manually (get/add/upsert/update/delete then commit()), never on one inside an active run() block.","commonSituations":"Porting manual-transaction code (begin -> ops -> commit) into run() and leaving the old commit() in place; trying to commit conditionally mid-callback; following older examples that predate run()'s auto-commit; wrapping run() in a helper that also commits.","solutions":["Delete the txn.commit() call inside the run() callback - run() commits automatically once the callback returns successfully","If you need explicit commit control, do not use run(): call txn.add/upsert/update/delete directly and then txn.commit() yourself","Move conditional commit logic into the callback (return early or raise to abort), letting run() decide when to commit"],"exampleFix":"# before\ntxn.run(lambda t: (t.add(ids=['a'], embeddings=[[0.1]]), t.commit()))\n\n# after - run() commits automatically\ntxn.run(lambda t: t.add(ids=['a'], embeddings=[[0.1]]))","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    txn.run(callback)\nexcept ValueError as e:\n    if 'cannot be called inside run()' in str(e):\n        # callback invoked txn.commit() itself; remove that call\n        raise RuntimeError('callback must not call txn.commit(); run() commits automatically')\n    raise","preventionTips":["Never call txn.commit() inside a run() callback - run() owns the commit and retries with a fresh transaction on conflict","Use run() for auto-retrying optimistic transactions; use manual ops + commit() only when you skip run() entirely","Keep callbacks side-effect-light: buffer reads/writes, return data, and let run() commit"],"tags":["chroma","transaction","api-misuse","python"],"backgroundTag":"commit-inside-managed-transaction","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}