chroma-core/chroma · error · ValueError

Expected where document operand value for operator {operator

Error message

Expected where document operand value for operator {operator} to be a non-empty str

What it means

validate_where_document requires the operand of $contains/$not_contains/$regex/$not_regex to be a NON-EMPTY string. An empty string ("") is rejected because matching an empty substring/pattern is meaningless in Chroma's document filter engine.

Source

Thrown at chromadb/api/types.py:1330

            )
        if operator == "$and" or operator == "$or":
            if not isinstance(operand, list):
                raise ValueError(
                    f"Expected document value for $and or $or to be a list of where document expressions, got {operand}"
                )
            if len(operand) <= 1:
                raise ValueError(
                    f"Expected document value for $and or $or to be a list with at least two where document expressions, got {operand}"
                )
            for where_document_expression in operand:
                validate_where_document(where_document_expression)
        # Value is $contains/$not_contains/$regex/$not_regex operator
        elif not isinstance(operand, str):
            raise ValueError(
                f"Expected where document operand value for operator {operator} to be a str, got {operand}"
            )
        elif len(operand) == 0:
            raise ValueError(
                f"Expected where document operand value for operator {operator} to be a non-empty str"
            )


def validate_include(include: Include, dissalowed: Optional[Include] = None) -> None:
    """Validates include to ensure it is a list of strings. Since get does not allow distances, allow_distances is used
    to control if distances is allowed"""

    if not isinstance(include, list):
        raise ValueError(f"Expected include to be a list, got {include}")
    for item in include:
        if not isinstance(item, str):
            raise ValueError(f"Expected include item to be a str, got {item}")

        # Get the valid items from the Literal type inside the List
        valid_items = get_args(get_args(Include)[0])
        if item not in valid_items:
            raise ValueError(

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Skip the where_document filter entirely when the value is empty instead of sending {"$contains": ""}
  2. Default optional filter variables to None and build the filter only if the value is truthy
  3. For search-as-you-type, guard the request with: if not query.strip(): return []

Example fix

# before
results = collection.query(query_texts=[q], where_document={"$contains": search_term})  # search_term == ""

# after
if search_term:
    results = collection.query(query_texts=[q], where_document={"$contains": search_term})
else:
    results = collection.query(query_texts=[q], n_results=5)
Defensive patterns

Strategy: validation

Validate before calling

def optional_contains(term: str | None) -> dict | None:
    """Return a $contains filter only for non-empty terms."""
    if term is None or not term.strip():
        return None
    return {"$contains": term}

wd = optional_contains(user_query)
kwargs = {"where_document": wd} if wd else {}
res = collection.query(query_texts=[q], n_results=5, **kwargs)

Type guard

def is_non_empty_str_operand(wd: dict) -> bool:
    if len(wd) != 1:
        return False
    op, operand = next(iter(wd.items()))
    return op in ("$contains", "$not_contains", "$regex", "$not_regex") and isinstance(operand, str) and len(operand) > 0

Try / catch

try:
    res = collection.query(query_texts=[q], where_document={"$contains": term}, n_results=5)
except ValueError as e:
    if "non-empty str" in str(e):
        res = collection.query(query_texts=[q], n_results=5)  # retry without the filter
    else:
        raise

Prevention

When it happens

Trigger: collection.get(where_document={"$contains": ""}) — typically the string comes from an f-string or variable that is empty at runtime, e.g. {"$contains": user_query} when user_query == "", or a config/env value that was never set.

Common situations: Search-as-you-type UIs issuing a query on every keystroke, including the empty input; optional filter parameters defaulting to "" instead of None; stripping whitespace from user input leaving "".

Related errors


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