{"record":{"id":"a1ebf6e0e568520e","repo":"langchain-ai/langchain","slug":"received-disallowed-operator-func-allowed-compa","errorCode":null,"errorMessage":"Received disallowed operator {func}. Allowed comparators are {self.allowed_operators}","messagePattern":"Received disallowed operator (.+?)\\. Allowed comparators are (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/structured_query.py","lineNumber":34,"sourceCode":"    \"\"\"Defines interface for IR translation using a visitor pattern.\"\"\"\n\n    allowed_comparators: Sequence[Comparator] | None = None\n    \"\"\"Allowed comparators for the visitor.\"\"\"\n\n    allowed_operators: Sequence[Operator] | None = None\n    \"\"\"Allowed operators for the visitor.\"\"\"\n\n    def _validate_func(self, func: Operator | Comparator) -> None:\n        if (\n            isinstance(func, Operator)\n            and self.allowed_operators is not None\n            and func not in self.allowed_operators\n        ):\n            msg = (\n                f\"Received disallowed operator {func}. Allowed \"\n                f\"comparators are {self.allowed_operators}\"\n            )\n            raise ValueError(msg)\n        if (\n            isinstance(func, Comparator)\n            and self.allowed_comparators is not None\n            and func not in self.allowed_comparators\n        ):\n            msg = (\n                f\"Received disallowed comparator {func}. Allowed \"\n                f\"comparators are {self.allowed_comparators}\"\n            )\n            raise ValueError(msg)\n\n    @abstractmethod\n    def visit_operation(self, operation: Operation) -> Any:\n        \"\"\"Translate an Operation.\n\n        Args:\n            operation: Operation to translate.\n        \"\"\"","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/structured_query.py#L16-L52","documentation":"Translator base class for structured-query translation (`langchain_core.structured_query.BaseTranslator`) validates that every `Operator` it is asked to visit is in the translator's `allowed_operators` set. Raised when a Visitor/translator receives a logical operator the target backend does not support — typically inside `visit_operation` during filter translation for a vector store.","triggerScenarios":"Translating a `FilterExpression` containing `and`/`or`/`not`/`in` operators to a vector store whose translator only allows a subset, e.g. sending an `in` operator to a store whose `allowed_operators = [Operator.AND, Operator.OR]`; self-querying retrievers built on stores with restricted operator support.","commonSituations":"Using `SelfQueryRetriever` with a vectorstore that does not support `in`/`not` and the LLM emits such a filter; switching a working self-query pipeline to a different backend (e.g. Pinecone → Chroma) with narrower operator support; custom translators forgetting to widen `allowed_operators`.","solutions":["Check `<translator>.allowed_operators` for your store and constrain the LLM's filter generation (adjust the self-query prompt/metadata schema) to only those operators.","Restructure the query so unsupported operators are not needed (e.g. expand `in` into an `or` chain if `or` is allowed).","If you own the translator subclass, extend `allowed_operators` and implement the corresponding `visit_operation` branches."],"exampleFix":"# before\nfilt = Operator.IN(...)  # sent to translator with allowed_operators=[AND, OR]\ntranslator.visit_operation(filt.astree)\n# after\nfilt = or_(Comparison('eq', 'tag', 'a'), Comparison('eq', 'tag', 'b'))\ntranslator.visit_operation(filt.astree)","handlingStrategy":"validation","validationCode":"allowed = set(translator.allowed_operators or [])\nops_in_filter = collect_operators(filter_expr)  # walk expr, gather Operator nodes\nunsupported = ops_in_filter - allowed\nif unsupported:\n    filter_expr = rewrite_to_supported(filter_expr, allowed)  # e.g. expand IN into OR","typeGuard":"def operator_allowed(translator, op) -> bool:\n    return translator.allowed_operators is None or op in translator.allowed_operators","tryCatchPattern":"try:\n    translated = translator.visit_operation(expr)\nexcept ValueError as e:\n    if 'disallowed operator' in str(e):\n        expr = simplify_filter(expr, allowed=set(translator.allowed_operators))\n        translated = translator.visit_operation(expr)\n    else:\n        raise","preventionTips":["Read the store translator's allowed_operators before generating filters.","Constrain self-query prompts to the supported operator set.","Prefer post-filtering in Python for exotic operators."],"tags":["structured-query","self-query-retriever","vector-store","filter-translation"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}