run-llama/llama_index · error · ValueError

Invalid operator: {operator}

Error message

Invalid operator: {operator}

What it means

The tail of `_process_filter_match`'s operator dispatch: every FilterOperator member is compared explicitly, and anything not matched by the preceding chain falls through to `raise ValueError(f"Invalid operator: {operator}")`. In practice this is reached when a raw string (e.g. "eq") is passed where a FilterOperator enum was expected, so none of the `operator == FilterOperator.X` comparisons match. It also fires if a new operator enum value exists that this llama-index-core version predates.

Source

Thrown at llama-index-core/llama_index/core/vector_stores/utils.py:157

                if isinstance(value, str) and isinstance(metadata_value, str):
                    return value in metadata_value
                raise TypeError(
                    "Both metadata_value and value should be strings to be used with a "
                    "TEXT_MATCH filter"
                )
            if operator == FilterOperator.TEXT_MATCH_INSENSITIVE:
                if isinstance(value, str) and isinstance(metadata_value, str):
                    return value.lower() in metadata_value.lower()
                raise TypeError(
                    "Both metadata_value and value should be strings to be used with a "
                    "TEXT_MATCH_INSENSITIVE filter"
                )
            if operator == FilterOperator.ALL:
                return all(val in metadata_value for val in value)
            if operator == FilterOperator.ANY:
                return any(val in metadata_value for val in value)

            raise ValueError(f"Invalid operator: {operator}")

        metadata = metadata_lookup_fn(node_id)

        filter_matches_list = []
        for filter_ in filter_list:
            if isinstance(filter_, MetadataFilters):
                raise ValueError("Nested MetadataFilters are not supported.")

            filter_matches = True
            metadata_value = metadata.get(filter_.key, None)
            if filter_.operator == FilterOperator.IS_EMPTY:
                filter_matches = (
                    metadata_value is None
                    or metadata_value == ""
                    or metadata_value == []
                )
            else:
                filter_matches = _process_filter_match(

View on GitHub (pinned to afd0fef371)

Solutions

  1. Always use the enum: `from llama_index.core.vector_stores import FilterOperator` and pass `FilterOperator.GTE` etc.
  2. Convert strings via `FilterOperator(value_str)` with try/except for config-driven inputs.
  3. Align versions: upgrade llama-index-core (and integration packs) together so operator enums match.
  4. Validate operators against `list(FilterOperator)` before building filters.

Example fix

# before
f = MetadataFilter(key="year", value=2020, operator="gte")  # falls through

# after
from llama_index.core.vector_stores import FilterOperator
f = MetadataFilter(key="year", value=2020, operator=FilterOperator.GTE)
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.vector_stores import FilterOperator

def coerce_operator(op):
    if isinstance(op, FilterOperator):
        return op
    try:
        return FilterOperator(op)
    except ValueError:
        raise ValueError(f"unknown filter operator: {op!r}; valid: {[m.value for m in FilterOperator]}")

Type guard

def is_valid_operator(op) -> bool:
    from llama_index.core.vector_stores import FilterOperator
    return isinstance(op, FilterOperator) and op in list(FilterOperator)

Try / catch

try:
    result = store.query(query)
except ValueError as e:
    if "Invalid operator" in str(e):
        raise ValueError("pass FilterOperator enum members, not strings") from e
    raise

Prevention

When it happens

Trigger: Constructing MetadataFilter with `operator="gte"` (a bare string) instead of `FilterOperator.GTE`; mixing llama-index versions where an integration emits a newer FilterOperator member than the installed core understands; passing a custom enum or None as operator.

Common situations: Copy-pasting filter code that uses string literals; config-driven filter builders (YAML/JSON) that read operator names as strings without conversion; version skew between llama-index-core and a vector-store integration pack.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/6c27f9bc436e9ae5. Report an issue: GitHub.