chroma-core/chroma · error · InvalidArgumentError
transactional update for id "{id}" requires a prior read pro
Error message
transactional update for id "{id}" requires a prior read proving the id is present What it means
Raised by _validate_write_precondition (chromadb/api/conditional_http.py:304) when a transactional update targets an id the transaction has not proven present. _known_present only contains ids actually returned by a prior get inside the same transaction, so updating a record you have not read (or that came back empty) is rejected before anything is buffered. This keeps the OCC commit anchored to a read set that genuinely observed the current state of every updated id.
Source
Thrown at chromadb/api/conditional_http.py:304
if id in call_ids:
raise InvalidArgumentError(
f'transactional write request contains duplicate id "{id}"'
)
call_ids.add(id)
if id in self._buffered_write_ids:
raise InvalidArgumentError(
f'transaction already has a buffered write for id "{id}"'
)
self._validate_write_precondition(operation, id)
def _validate_write_precondition(self, operation: str, id: str) -> None:
if operation == "add" and id not in self._known_absent:
raise InvalidArgumentError(
f'transactional add for id "{id}" requires a prior read '
"proving the id is absent"
)
if operation == "update" and id not in self._known_present:
raise InvalidArgumentError(
f'transactional update for id "{id}" requires a prior read '
"proving the id is present"
)
if operation == "delete" and id not in self._known_present:
raise InvalidArgumentError(
f'transactional delete for id "{id}" requires a prior read '
"proving the id is present"
)
def require_conditional_http_transaction(
transaction: object,
) -> ConditionalHttpTransaction:
if not isinstance(transaction, ConditionalHttpTransaction):
raise ValueError("invalid conditional transaction for HTTP client")
return transaction
View on GitHub (pinned to aecdd12c8a)
Solutions
- Do an id-based get in the same transaction first and update only the ids it returned
- Use upsert when the record may or may not exist
- If the id was absent, add it after the read proves absence instead of updating
Example fix
# before
with client.transaction():
collection.update(ids=["doc1"], metadatas=[{"v": 2}])
# after
with client.transaction():
got = collection.get(ids=["doc1"])
if got["ids"]:
collection.update(ids=["doc1"], metadatas=[{"v": 2}])
else:
collection.add(ids=["doc1"], embeddings=[emb]) Defensive patterns
Strategy: validation
Validate before calling
def txn_update(collection, ids, **fields):
got = collection.get(ids=ids) # proves presence inside the txn
present = list(got["ids"])
if present:
collection.update(ids=present, **fields)
return present Try / catch
from chromadb.errors import InvalidArgumentError
try:
collection.update(ids=ids, metadatas=metas)
except InvalidArgumentError as e:
if "requires a prior read" in str(e):
got = collection.get(ids=ids)
collection.update(ids=list(got["ids"]), metadatas=metas)
else:
raise Prevention
- Update only ids returned by an id-based get in the same transaction
- Use upsert when presence is uncertain
- Do not derive existence from application state; derive it from the transactional read
When it happens
Trigger: collection.update(ids=["doc1"], ...) inside a transaction without a preceding get that returned "doc1"; reading with where filters that returned other ids; reading the id in a different transaction; the get returning nothing because the id does not exist (then update is the wrong operation - the record is absent).
Common situations: Fire-and-forget update flows moved into a transaction without adding the read step; assuming a record exists from application state rather than from a transactional read; batch updates generated from an external source (e.g. a queue) without verifying presence first.
Related errors
- transactional add for id "{id}" requires a prior read provin
- transactional delete for id "{id}" requires a prior read pro
- transactional filter reads require a positive limit
- transaction already has a buffered write for id "{id}"
- conditional transaction has no collection scope
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/a826d8214fabec28.
Report an issue: GitHub.