{"record":{"id":"337b5dbf405a980b","repo":"microsoft/semantic-kernel","slug":"binary-operator-type-node-op-name-is-not","errorCode":null,"errorMessage":"Binary operator '{type(node.op).__name__}' is not allowed in filter expressions.","messagePattern":"Binary operator '(.+?)' is not allowed in filter expressions\\.","errorType":"exception","errorClass":"VectorStoreOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/in_memory.py","lineNumber":270,"sourceCode":"    def _eval_BinOp(self, node: ast.BinOp, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate a binary operator.\"\"\"\n        left = self.evaluate(node.left, context)\n        right = self.evaluate(node.right, context)\n\n        if isinstance(node.op, ast.Add):\n            return self._safe_add(left, right)\n        if isinstance(node.op, ast.Sub):\n            return self._safe_numeric_operation(node.op, left, right, lambda a, b: a - b)\n        if isinstance(node.op, ast.Mult):\n            return self._safe_mult(left, right)\n        if isinstance(node.op, ast.Div):\n            return self._safe_numeric_operation(node.op, left, right, lambda a, b: a / b)\n        if isinstance(node.op, ast.Mod):\n            return self._safe_numeric_operation(node.op, left, right, lambda a, b: a % b)\n        if isinstance(node.op, ast.FloorDiv):\n            return self._safe_numeric_operation(node.op, left, right, lambda a, b: a // b)\n\n        raise VectorStoreOperationException(\n            f\"Binary operator '{type(node.op).__name__}' is not allowed in filter expressions.\"\n        )\n\n    def _eval_Call(self, node: ast.Call, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate a function or method call.\"\"\"\n        args = [self.evaluate(arg, context) for arg in node.args]\n\n        if isinstance(node.func, ast.Name):\n            try:\n                func = self._direct_call_functions[node.func.id]\n            except KeyError as e:\n                raise VectorStoreOperationException(\n                    f\"Function '{node.func.id}' is only supported as a method call in filter expressions.\"\n                ) from e\n            return func(*args)\n\n        if isinstance(node.func, ast.Attribute):\n            target = self.evaluate(node.func.value, context)","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/in_memory.py#L252-L288","documentation":"_eval_BinOp supports only Add, Sub, Mult, Div, Mod, and FloorDiv. Any other binary operator (Pow '**', LShift/RShift, BitAnd/BitOr/BitXor, MatMult) raises VectorStoreOperationException. The static allowlist covers exactly those six operators, so others are rejected at parse time first; the eval-time branch is the safety net for subclass-widened allowlists.","triggerScenarios":"A filter like lambda x: x.a ** 2, lambda x: x.a | x.b, or lambda x: x.a << 2; reaches the evaluator only if the extra operator nodes were added to allowed_filter_ast_nodes.","commonSituations":"Using power or bitwise operations in a computed comparison; attempting set-like ops with bitwise-or.","solutions":["Rewrite without unsupported operators (e.g. x.a * x.a instead of x.a ** 2).","Do not add Pow/shift/bitwise operator nodes to allowed_filter_ast_nodes without a matching evaluator branch."],"exampleFix":"# before\nVectorSearchOptions(filter=lambda x: x.a ** 2 > 100)  # Pow -> static reject (or [1316])\n\n# after\nVectorSearchOptions(filter=lambda x: x.a * x.a > 100)","handlingStrategy":"validation","validationCode":"import ast\nALLOWED = {ast.Add, ast.Sub, ast.Mult, ast.Div, ast.Mod, ast.FloorDiv}\ndef uses_only_allowed_binops(filter_str: str) -> None:\n    for node in ast.walk(ast.parse(filter_str, mode='eval')):\n        if isinstance(node, ast.BinOp) and type(node.op) not in ALLOWED:\n            raise ValueError(f\"binary operator {type(node.op).__name__} is not allowed in filters\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only +, -, *, /, %, // in filter arithmetic.","Rewrite x ** 2 as x * x; avoid bitwise operators."],"tags":["in-memory","filter","ast"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}