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

  1. Always obtain the transaction from the same HTTP client instance you commit with (its begin/create transaction API)
  2. Type-check before passing: isinstance(transaction, ConditionalHttpTransaction)
  3. 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

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


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