chroma-core/chroma · error · ValueError
invalid conditional transaction for HTTP client
Error message
invalid conditional transaction for HTTP client
What it means
require_conditional_http_transaction (chromadb/api/conditional_http.py:319) raises this ValueError when the transaction object handed to the HTTP client's conditional-transaction methods is not a ConditionalHttpTransaction instance. The client refuses any substitute - a dict, None, a mock, or a transaction object from another client implementation - because it drives the transaction's internal buffers (scope, read sets, buffered operations) directly.
Source
Thrown at chromadb/api/conditional_http.py:319
"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
- Always obtain the transaction from the same HTTP client instance you commit with (its begin/create transaction API)
- Type-check before passing: isinstance(transaction, ConditionalHttpTransaction)
- In tests, keep fakes behind your own interface, not at the chromadb transaction boundary
Example fix
# before
txn = {"operations": []} # not a real transaction
client._commit_conditional(txn) # ValueError
# after
txn = client.create_transaction() # ConditionalHttpTransaction from the client
client._commit_conditional(txn) Defensive patterns
Strategy: type-guard
Validate before calling
from chromadb.api.conditional_http import ConditionalHttpTransaction
def commit_txn(client, txn):
if not isinstance(txn, ConditionalHttpTransaction):
raise TypeError("txn must come from the HTTP client's transaction API")
return client._commit_conditional(txn) Type guard
from chromadb.api.conditional_http import ConditionalHttpTransaction
from typing import Any
def is_conditional_http_transaction(obj: Any) -> bool:
"""Type guard: True when obj is a ConditionalHttpTransaction."""
return isinstance(obj, ConditionalHttpTransaction) Try / catch
try:
require_conditional_http_transaction(txn)
except ValueError as e:
if "invalid conditional transaction" in str(e):
txn = client.create_transaction() # start a real one
else:
raise Prevention
- Obtain the transaction from the same HTTP client you commit with
- Never substitute dicts, mocks, or other clients' transaction objects at the chromadb boundary
- Keep test fakes behind your own abstraction, not inside chromadb calls
When it happens
Trigger: Passing a hand-constructed object, dict, or None where the HTTP client expects the ConditionalHttpTransaction returned by its own begin/create-transaction call; mixing transaction objects between an AsyncClient or other API implementation and the sync HTTP client; test doubles replacing the transaction.
Common situations: Wrapper libraries or ORMs building their own transaction abstraction over chromadb; copy-pasting code across client types (segment/local vs http); mocking in unit tests leaking into integration paths.
Related errors
- conditional transaction has no collection scope
- 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/09ebf0d1333fd588.
Report an issue: GitHub.