chroma-core/chroma · error · ValueError
ids must be provided for transactional delete
Error message
ids must be provided for transactional delete
What it means
Synchronous twin of the async error: ConditionalCollectionTransaction.delete() only supports delete-by-ID. The request is built with where/where_document forced to None; if the validated ids come back None, the buffered-write transaction cannot proceed and raises before contacting the server.
Source
Thrown at chromadb/api/models/ConditionalCollectionTransaction.py:260
lambda: self._collection._client._conditional_upsert(
transaction=self._transaction,
collection_id=self._collection.id,
ids=upsert_request["ids"],
embeddings=upsert_request["embeddings"],
metadatas=upsert_request["metadatas"],
documents=upsert_request["documents"],
uris=upsert_request["uris"],
tenant=self._collection.tenant,
database=self._collection.database,
)
)
def delete(self, ids: OneOrMany[ID]) -> None:
delete_request = self._collection._validate_and_prepare_delete_request(
ids, None, None
)
if delete_request["ids"] is None:
raise ValueError("ids must be provided for transactional delete")
self._run_transaction_operation(
lambda: self._collection._client._conditional_delete(
transaction=self._transaction,
collection_id=self._collection.id,
ids=delete_request["ids"],
tenant=self._collection.tenant,
database=self._collection.database,
)
)
def commit(self) -> ConditionalCommitResult:
if self._commit_blocked_by_run:
raise ValueError("txn.commit() cannot be called inside run()")
return self._commit_after_run()
View on GitHub (pinned to aecdd12c8a)
Solutions
- Pass an explicit list of IDs: `txn.delete(["id-1", "id-2"])`
- Collect IDs first with `txn.get(where=..., include=[])` and delete those in the same transaction
- Use non-transactional `collection.delete(where=...)` when predicate deletes are required
Example fix
# before
txn.delete(ids=None)
# after
if not ids:
raise ValueError("transactional delete requires ids")
txn.delete(ids=ids) Defensive patterns
Strategy: validation
Validate before calling
ids = list(ids or [])
if not ids:
raise ValueError("transactional delete requires explicit non-empty ids")
txn.delete(ids=ids) Type guard
from typing import Any, List, TypeGuard
def is_non_empty_id_list(v: Any) -> TypeGuard[List[str]]:
return isinstance(v, (list, tuple)) and len(v) > 0 and all(isinstance(i, str) for i in v) Prevention
- Transactions are delete-by-id only; resolve filters to ids with txn.get() first
- Assert ids non-empty immediately before txn.delete inside the callback
- Fall back to collection.delete(where=...) when predicate deletes are required
When it happens
Trigger: Calling `txn.delete(ids)` inside `collection.transaction.run(...)` on a sync Collection with an ids value that passes the presence check but unpacks to None (None-equivalent/empty/malformed value).
Common situations: Moving filter-based deletes into optimistic transactions; passing a variable that is None at runtime inside the run callback.
Related errors
- ids must be provided for transactional delete
- At least one of ids, where, or where_document must be provid
- max_retries must be a non-negative integer
- Knn limit must be a positive integer
- Knn key must be a string or Key instance
AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16).
Data as JSON: /api/errors/bcf3d00c17779963.
Report an issue: GitHub.