chroma-core/chroma · error · NotImplementedError

Conditional transactions are only supported when connecting

Error message

Conditional transactions are only supported when connecting to a Chroma server via HttpClient.

What it means

Conditional transactions (the collection.conditional API: conditional add/update/upsert/delete/get/commit with optimistic-concurrency semantics) are implemented only on the HTTP transport. Before dispatching, Client._require_http_conditional_transactions() checks settings.chroma_server_http_port; when it is None — i.e. you are on PersistentClient/EphemeralClient (embedded server, no HTTP port) — the call raises NotImplementedError.

Source

Thrown at chromadb/api/client.py:65

    A client internally stores its tenant and database and proxies calls to a
    Server API instance of Chroma. It treats the Server API and corresponding System
    as a singleton, so multiple clients connecting to the same resource will share the
    same API instance.

    Client implementations should be implement their own API-caching strategies.
    """

    tenant: str = DEFAULT_TENANT
    database: str = DEFAULT_DATABASE

    _server: ServerAPI
    # An internal admin client for verifying that databases and tenants exist
    _admin_client: AdminAPI
    _closed: bool = False

    def _require_http_conditional_transactions(self) -> ServerAPI:
        if self._system.settings.chroma_server_http_port is None:
            raise NotImplementedError(
                "Conditional transactions are only supported when connecting "
                "to a Chroma server via HttpClient."
            )
        return self._server

    # region Initialization
    def __init__(
        self,
        tenant: Optional[str] = DEFAULT_TENANT,
        database: Optional[str] = DEFAULT_DATABASE,
        settings: Settings = Settings(),
    ) -> None:
        super().__init__(settings=settings)
        try:
            if tenant is not None:
                self.tenant = tenant
            if database is not None:
                self.database = database

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Switch to the HTTP client against a running server: client = chromadb.HttpClient(host=..., port=...).
  2. Or replace the conditional-transaction logic with plain add/upsert (losing optimistic concurrency guarantees).
  3. Keep embedded mode but implement your own locking/version check outside Chroma.

Example fix

# before
client = chromadb.PersistentClient(path="./data")
client.get_collection("docs").conditional.add(...)  # NotImplementedError

# after
client = chromadb.HttpClient(host="localhost", port=8000)
client.get_collection("docs").conditional.add(...)
Defensive patterns

Strategy: type-guard

Validate before calling

def supports_conditional_txns(client) -> bool:
    return client._system.settings.chroma_server_http_port is not None

if not supports_conditional_txns(client):
    raise RuntimeError("conditional transactions need chromadb.HttpClient")

Type guard

import chromadb

def is_http_client(client) -> bool:
    return isinstance(client, chromadb.api.client.Client) and (
        client._system.settings.chroma_server_http_port is not None
    )

Try / catch

try:
    collection.conditional.add(...)
except NotImplementedError:
    raise RuntimeError(
        "switch to chromadb.HttpClient(host=..., port=...) to use conditional transactions"
    )

Prevention

When it happens

Trigger: client = chromadb.PersistentClient(path='./db'); client.get_collection('c').conditional.add(...) — same for EphemeralClient; using Client(Settings(...)) without any chroma_server_http_port configured and then touching any .conditional* method.

Common situations: Prototyping with PersistentClient, then wiring in compare-and-swap writes; switching a HttpClient-based app to embedded mode for tests and having conditional transaction calls break.

Related errors


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