chroma-core/chroma · error · ValueError
conditional transaction has no collection scope
Error message
conditional transaction has no collection scope
What it means
Raised by ConditionalHttpTransaction._require_scope (chromadb/api/conditional_http.py:233) when a scope-requiring step (recording a get result or building the commit payload) runs on a transaction that never bound itself to a collection. The scope is a frozen (collection_id, tenant, database) tuple recorded on the first prepare_get/buffer_* call; every later step must reuse it. In practice this is a defensive invariant: a transaction with buffered operations always has a scope, so hitting it usually means the transaction lifecycle was manipulated directly or a client bug is present.
Source
Thrown at chromadb/api/conditional_http.py:233
self._closed = True
def _ensure_open(self) -> None:
if self._closed:
raise ValueError("conditional transaction is closed")
def _record_scope(
self, collection_id: UUID, tenant: str, database: str
) -> ConditionalHttpScope:
scope = ConditionalHttpScope(str(collection_id), tenant, database)
if self._scope is None:
self._scope = scope
elif self._scope != scope:
raise ValueError("conditional transaction cannot span collections")
return scope
def _require_scope(self) -> ConditionalHttpScope:
if self._scope is None:
raise ValueError("conditional transaction has no collection scope")
return self._scope
def _validate_get_request(self, request_payload: ConditionalHttpGetPayload) -> None:
ids = request_payload.get("ids")
if ids is not None:
for id in ids:
if id in self._buffered_write_ids:
raise _invalid_read_after_write(id)
return
limit = request_payload.get("limit")
if not isinstance(limit, int) or limit <= 0:
raise InvalidArgumentError(
"transactional filter reads require a positive limit"
)
def _validate_read_token(
self, expected_read_token: Optional[int], actual_read_token: Optional[int]View on GitHub (pinned to aecdd12c8a)
Solutions
- Start every transaction with at least one scoped operation (a get or a buffered write) before requesting the commit payload
- Do not construct or drive ConditionalHttpTransaction yourself; obtain it from the HTTP client's transaction API so scope is always recorded first
- If you only reached this via the public client API, upgrade chromadb to a consistent version and report the reproduction
Example fix
# before txn = ConditionalHttpTransaction() payload = txn.prepare_commit_payload() # no operation ever recorded # after collection.get(ids=["doc1"]) # first read records the scope collection.add(ids=["doc2"], embeddings=[emb]) txn.prepare_commit_payload() # scope now present
Defensive patterns
Strategy: validation
Validate before calling
from chromadb.api.conditional_http import ConditionalHttpTransaction
def safe_commit(txn):
# a transaction with any buffered operation always has a scope;
# commit only after at least one read/write against a collection
if not txn._operations: # nothing buffered: commit is a no-op
txn.close()
return None
return txn.prepare_commit_payload() Try / catch
try:
txn.prepare_commit_payload()
except ValueError as e:
if "no collection scope" in str(e):
# transaction was misused: restart it and perform a read/write first
...
raise Prevention
- Always perform the first read or write before requesting a commit
- Never construct ConditionalHttpTransaction yourself; use the client's transaction API
- Treat this error as an invariant violation: log the transaction lifecycle that led to it
When it happens
Trigger: Calling prepare_commit_payload() or record_get() on a ConditionalHttpTransaction instance that never received a prepare_get/buffer_add/buffer_update/buffer_upsert/buffer_delete call for any collection. Not reachable through the normal client flow where the first read/write precedes the commit.
Common situations: Test code or custom wrappers that construct ConditionalHttpTransaction() manually and commit without operations; reusing or resetting transaction internals; a chromadb version mismatch between the client wrapper and this module after a partial upgrade.
Related errors
- invalid conditional transaction for HTTP client
- transactional filter reads require a positive limit
- transactional write request contains duplicate id "{id}"
- transaction already has a buffered write for id "{id}"
- transactional add for id "{id}" requires a prior read provin
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/9077b44008c5a51f.
Report an issue: GitHub.