chroma-core/chroma · error · InvalidArgumentError

transactional delete for id "{id}" requires a prior read pro

Error message

transactional delete 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:309) when a transactional delete targets an id the transaction has not proven present. Like add and update, delete follows the read-then-write protocol: only ids returned by a prior get inside the same transaction land in _known_present, and deleting an unobserved id is rejected. This makes deletes conflict-detectable via the OCC read token at commit time instead of silently no-oping.

Source

Thrown at chromadb/api/conditional_http.py:309

            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


def _invalid_read_after_write(id: str) -> InvalidArgumentError:
    return InvalidArgumentError(
        f'cannot transactionally read id "{id}" after buffering a write for it'
    )

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Read the ids with an id-based get inside the same transaction, then delete only the ids that came back
  2. Filter your id list against the get result before calling delete
  3. Delete unobserved ids outside the transaction, or accept that transactional deletes require the read by design

Example fix

# before
with client.transaction():
    collection.delete(ids=["gone", "here"])
# after
with client.transaction():
    got = collection.get(ids=["gone", "here"])
    present = got["ids"]
    if present:
        collection.delete(ids=present)
Defensive patterns

Strategy: validation

Validate before calling

def txn_delete(collection, ids):
    got = collection.get(ids=ids)          # proves presence inside the txn
    present = list(got["ids"])
    if present:
        collection.delete(ids=present)
    return set(ids) - set(present)         # ids that were already absent

Try / catch

from chromadb.errors import InvalidArgumentError

try:
    collection.delete(ids=ids)
except InvalidArgumentError as e:
    if "requires a prior read" in str(e):
        got = collection.get(ids=ids)
        if got["ids"]:
            collection.delete(ids=list(got["ids"]))
    else:
        raise

Prevention

When it happens

Trigger: collection.delete(ids=["doc1"]) inside a transaction with no prior get returning "doc1"; deleting based on a stale application-side existence check; the earlier get using where filters rather than explicit ids.

Common situations: Cleanup jobs that delete by a list of ids gathered outside the transaction; retrying a delete in a new transaction after a conflict without re-reading; id lists built from another system (CMS, queue) where some ids were already removed.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/87321162957dbfd2. Report an issue: GitHub.