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] = NoneView on GitHub (pinned to afd0fef371)
Solutions
- Restrict each filter to `FilterOperator.EQ` (or construct with `ExactMatchFilter(key=..., value=...)`).
- 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=...)`).
- Flatten nested MetadataFilters groups before the legacy conversion.
- 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
- Use ExactMatchFilter (or FilterOperator.EQ) for stores on the legacy path.
- Do not nest MetadataFilters when the target uses legacy_filters().
- Encapsulate filter construction per backend instead of sharing one rich filter object.
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
- Cannot filter stores that were persisted without metadata. P
- extra_filters cannot be OR condition
- SimpleVectorStore does not store nodes directly.
- Invalid query mode: {query.mode}
- No existing {__name__} found at {persist_path}, skipping loa
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/e32e6ae760758c03.
Report an issue: GitHub.