run-llama/llama_index · error · ValueError

Vector Store only supports exact match filters. Please use E

Error message

Vector Store only supports exact match filters. Please use ExactMatchFilter or FilterOperator.EQ instead.

What it means

`MetadataFilters.legacy_filters` converts a modern filter list into the older ExactMatchFilter representation that simple/legacy vector stores consume. Any nested MetadataFilters object or any filter whose operator is not FilterOperator.EQ cannot be represented as an exact match, so the conversion raises this ValueError. It protects downstream stores that can only evaluate key == value.

Source

Thrown at llama-index-core/llama_index/core/vector_stores/types.py:195

            condition: FilterCondition to combine different filters.

        """
        return cls(
            filters=[
                MetadataFilter.from_dict(filter_dict) for filter_dict in filter_dicts
            ],
            condition=condition,
        )

    def legacy_filters(self) -> List[ExactMatchFilter]:
        """Convert MetadataFilters to legacy ExactMatchFilters."""
        filters = []
        for filter in self.filters:
            if (
                isinstance(filter, MetadataFilters)
                or filter.operator != FilterOperator.EQ
            ):
                raise ValueError(
                    "Vector Store only supports exact match filters. "
                    "Please use ExactMatchFilter or FilterOperator.EQ instead."
                )
            filters.append(ExactMatchFilter(key=filter.key, value=filter.value))
        return filters


class VectorStoreQuerySpec(BaseModel):
    """
    Schema for a structured request for vector store
    (i.e. to be converted to a VectorStoreQuery).

    Currently only used by VectorIndexAutoRetriever.
    """

    query: str
    filters: List[MetadataFilter]
    top_k: Optional[int] = None

View on GitHub (pinned to afd0fef371)

Solutions

  1. Restrict each filter to `FilterOperator.EQ` (or construct with `ExactMatchFilter(key=..., value=...)`).
  2. If you need range/set/text operators, move to a store + code path that consumes modern MetadataFilters (e.g. the store's native `query(filters=...)`).
  3. Flatten nested MetadataFilters groups before the legacy conversion.
  4. Audit any shared filter-building helpers so they cannot emit non-EQ operators to legacy stores.

Example fix

# before
filters = MetadataFilters(filters=[MetadataFilter(key="year", value=2020, operator=FilterOperator.GTE)])
legacy = filters.legacy_filters()  # ValueError

# after
filters = MetadataFilters(filters=[ExactMatchFilter(key="year", value=2020)])
legacy = filters.legacy_filters()
Defensive patterns

Strategy: validation

Validate before calling

from llama_index.core.vector_stores.types import FilterOperator, MetadataFilters

def filters_are_legacy_safe(filters: MetadataFilters) -> bool:
    return all(
        not isinstance(f, MetadataFilters) and f.operator == FilterOperator.EQ
        for f in filters.filters
    )

Try / catch

try:
    legacy = filters.legacy_filters()
except ValueError as e:
    if "exact match" in str(e):
        raise ValueError("switch this store path to native MetadataFilters queries") from e
    raise

Prevention

When it happens

Trigger: Calling `filters.legacy_filters()` (directly or via a store/retriever that uses the legacy path) with filters containing `FilterOperator.GT`, `IN`, `TEXT_MATCH`, `NE`, etc., or with a nested `MetadataFilters` inside `filters=[...]`; e.g. querying SimpleVectorStore-backed legacy components with range filters.

Common situations: Upgrading filter code from ExactMatchFilter to the richer MetadataFilter API while the backing store only supports the legacy path; mixing advanced operators into examples originally written for Pinecone's legacy exact-match interface; composing nested filter groups (AND of ORs) and passing them to a legacy store.

Related errors


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