{"record":{"id":"fce011d45fe9549a","repo":"deepset-ai/haystack","slug":"invalid-filter-syntax-see-https-docs-haystack-d-fce011","errorCode":null,"errorMessage":"Invalid filter syntax. See https://docs.haystack.deepset.ai/docs/metadata-filtering for details.","messagePattern":"Invalid filter syntax\\. See https://docs\\.haystack\\.deepset\\.ai/docs/metadata-filtering for details\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"haystack/document_stores/in_memory/document_store.py","lineNumber":535,"sourceCode":"\n            # Update statistics accordingly\n            doc_stats = self._bm25_attr.pop(doc_id)\n            freq = doc_stats.freq_token\n            doc_len = doc_stats.doc_len\n\n            self._freq_vocab_for_idf.subtract(Counter(freq.keys()))\n            for token in freq:\n                if self._freq_vocab_for_idf[token] <= 0:\n                    del self._freq_vocab_for_idf[token]\n            try:\n                self._avg_doc_len = (self._avg_doc_len * (len(self._bm25_attr) + 1) - doc_len) / len(self._bm25_attr)\n            except ZeroDivisionError:\n                self._avg_doc_len = 0\n\n    @staticmethod\n    def _validate_filters(filters: dict[str, Any] | None) -> None:\n        if filters and \"operator\" not in filters and \"conditions\" not in filters:\n            raise ValueError(\n                \"Invalid filter syntax. See https://docs.haystack.deepset.ai/docs/metadata-filtering for details.\"\n            )\n\n    def delete_all_documents(self) -> None:\n        \"\"\"\n        Deletes all documents in the document store.\n        \"\"\"\n        if self._shared:\n            _STORAGES[self.index] = {}\n            _BM25_STATS_STORAGES[self.index] = {}\n            _AVERAGE_DOC_LEN_STORAGES[self.index] = 0.0\n            _FREQ_VOCAB_FOR_IDF_STORAGES[self.index] = Counter()\n        else:\n            self._local_storage = {}\n            self._local_bm25_attr = {}\n            self._local_avg_doc_len = 0.0\n            self._local_freq_vocab_for_idf = Counter()\n","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/document_stores/in_memory/document_store.py#L517-L553","documentation":"InMemoryDocumentStore._validate_filters raises ValueError when a filters dict is provided but contains neither an 'operator' nor a 'conditions' key, meaning it does not follow Haystack's documented metadata filtering syntax.","triggerScenarios":"Calling filter_documents, embedding_retrieval, or similar with a malformed dict like {\"field\": \"meta.x\", \"operator\": \"==\", \"value\": 1} at the top level instead of wrapping it in {\"operator\": \"AND\", \"conditions\": [...]}.","commonSituations":"Porting code written for other frameworks' flat filter syntax, hand-built filter dicts missing the top-level operator, upgrading from older Haystack 1.x filter formats.","solutions":["Wrap the comparison in the documented syntax: {\"operator\": \"AND\", \"conditions\": [{\"field\": \"...\", \"operator\": \"==\", \"value\": ...}]}","Use the shorthand single-comparison form {\"field\": ..., \"operator\": ..., \"value\": ...} which the engine also accepts via normalize (only if your version supports it)","Consult https://docs.haystack.deepset.ai/docs/metadata-filtering and validate the dict shape before calling"],"exampleFix":"// before\nstore.filter_documents({\"field\": \"meta.genre\", \"operator\": \"==\", \"value\": \"crime\"})\n// wrapped incorrectly without operator/conditions keys at top level\n// after\nstore.filter_documents({\"operator\": \"AND\", \"conditions\": [{\"field\": \"meta.genre\", \"operator\": \"==\", \"value\": \"crime\"}]})","handlingStrategy":"validation","validationCode":"def is_valid_haystack_filter(f):\n    if f is None:\n        return True\n    return isinstance(f, dict) and (\"operator\" in f or \"conditions\" in f)\n\nassert is_valid_haystack_filter(filters), \"filters need top-level 'operator'/'conditions'\"","typeGuard":"def is_filter_dict(f) -> bool:\n    return isinstance(f, dict) and (\"operator\" in f or \"conditions\" in f)","tryCatchPattern":"try:\n    docs = store.filter_documents(filters=filters)\nexcept ValueError as e:\n    if \"Invalid filter syntax\" in str(e):\n        docs = store.filter_documents(filters={\"operator\": \"AND\", \"conditions\": [filters]})\n    else:\n        raise","preventionTips":["Always build filters with a top-level 'operator' and 'conditions' per Haystack docs","Reuse a single filter-builder helper instead of hand-writing filter dicts","Check the metadata-filtering docs page when migrating filter code from other frameworks"],"tags":["document-store","filters","validation","python"],"backgroundTag":"invalid-filter-syntax","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}