{"record":{"id":"e32e6ae760758c03","repo":"run-llama/llama_index","slug":"vector-store-only-supports-exact-match-filters-pl","errorCode":null,"errorMessage":"Vector Store only supports exact match filters. Please use ExactMatchFilter or FilterOperator.EQ instead.","messagePattern":"Vector Store only supports exact match filters\\. Please use ExactMatchFilter or FilterOperator\\.EQ instead\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/vector_stores/types.py","lineNumber":195,"sourceCode":"            condition: FilterCondition to combine different filters.\n\n        \"\"\"\n        return cls(\n            filters=[\n                MetadataFilter.from_dict(filter_dict) for filter_dict in filter_dicts\n            ],\n            condition=condition,\n        )\n\n    def legacy_filters(self) -> List[ExactMatchFilter]:\n        \"\"\"Convert MetadataFilters to legacy ExactMatchFilters.\"\"\"\n        filters = []\n        for filter in self.filters:\n            if (\n                isinstance(filter, MetadataFilters)\n                or filter.operator != FilterOperator.EQ\n            ):\n                raise ValueError(\n                    \"Vector Store only supports exact match filters. \"\n                    \"Please use ExactMatchFilter or FilterOperator.EQ instead.\"\n                )\n            filters.append(ExactMatchFilter(key=filter.key, value=filter.value))\n        return filters\n\n\nclass VectorStoreQuerySpec(BaseModel):\n    \"\"\"\n    Schema for a structured request for vector store\n    (i.e. to be converted to a VectorStoreQuery).\n\n    Currently only used by VectorIndexAutoRetriever.\n    \"\"\"\n\n    query: str\n    filters: List[MetadataFilter]\n    top_k: Optional[int] = None","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/vector_stores/types.py#L177-L213","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nfilters = MetadataFilters(filters=[MetadataFilter(key=\"year\", value=2020, operator=FilterOperator.GTE)])\nlegacy = filters.legacy_filters()  # ValueError\n\n# after\nfilters = MetadataFilters(filters=[ExactMatchFilter(key=\"year\", value=2020)])\nlegacy = filters.legacy_filters()","handlingStrategy":"validation","validationCode":"from llama_index.core.vector_stores.types import FilterOperator, MetadataFilters\n\ndef filters_are_legacy_safe(filters: MetadataFilters) -> bool:\n    return all(\n        not isinstance(f, MetadataFilters) and f.operator == FilterOperator.EQ\n        for f in filters.filters\n    )","typeGuard":null,"tryCatchPattern":"try:\n    legacy = filters.legacy_filters()\nexcept ValueError as e:\n    if \"exact match\" in str(e):\n        raise ValueError(\"switch this store path to native MetadataFilters queries\") from e\n    raise","preventionTips":["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."],"tags":["metadata-filters","legacy-api","vector-store","python"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}