{"record":{"id":"50f88d214bd0a3e5","repo":"microsoft/semantic-kernel","slug":"use-of-name-node-id-is-not-allowed-in-filter-e","errorCode":null,"errorMessage":"Use of name '{node.id}' is not allowed in filter expressions.","messagePattern":"Use of name '(.+?)' is not allowed in filter expressions\\.","errorType":"exception","errorClass":"VectorStoreOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/in_memory.py","lineNumber":155,"sourceCode":"        if evaluator is None:\n            raise VectorStoreOperationException(\n                f\"AST node type '{type(node).__name__}' is not supported during filter evaluation.\"\n            )\n        return evaluator(node, context)\n\n    def _eval_Constant(self, node: ast.Constant, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate a constant literal.\"\"\"\n        del context\n        if isinstance(node.value, str) and len(node.value) > self._max_literal_collection_size:\n            raise VectorStoreOperationException(\n                \"String literals in filter expressions exceed the maximum allowed size.\"\n            )\n        return node.value\n\n    def _eval_Name(self, node: ast.Name, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate a variable reference.\"\"\"\n        if node.id not in context:\n            raise VectorStoreOperationException(f\"Use of name '{node.id}' is not allowed in filter expressions.\")\n        return context[node.id]\n\n    def _eval_Attribute(self, node: ast.Attribute, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate an attribute access.\"\"\"\n        if node.attr in self._blocked_attributes:\n            raise VectorStoreOperationException(\n                f\"Access to attribute '{node.attr}' is not allowed in filter expressions.\"\n            )\n        value = self.evaluate(node.value, context)\n        try:\n            return ReadOnlyAttributeDict._wrap_value(getattr(value, node.attr))\n        except AttributeError as e:\n            raise VectorStoreOperationException(\n                f\"Attribute '{node.attr}' is not available in filter expressions.\"\n            ) from e\n\n    def _eval_Subscript(self, node: ast.Subscript, context: Mapping[str, Any]) -> Any:\n        \"\"\"Evaluate an index or slice operation.\"\"\"","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/in_memory.py#L137-L173","documentation":"At evaluation time _eval_Name only resolves identifiers present in the context dict, which contains exactly the lambda parameters. Any other Name raises VectorStoreOperationException. The static parse-time check already rejects names that are not lambda parameters, so this runtime branch is a safety net that fires when the static Name restriction was relaxed or an edge case (e.g. a comprehension variable) slipped through.","triggerScenarios":"A filter referencing a free/global variable such as lambda x: x.score > THRESHOLD where THRESHOLD is a module-level name; this passes static validation only if the static Name check was loosened, then fails at evaluation.","commonSituations":"Writing a filter that closes over an outer constant instead of inlining it; subclassing to relax the Name allowlist; copying a lambda from elsewhere that depends on enclosing scope.","solutions":["Inline the constant into the filter body: lambda x: x.score > 10.","Keep the static Name restriction intact so only lambda parameters are referenced.","If you must parameterize, rebuild the filter string with the value interpolated before parsing."],"exampleFix":"# before\nTHRESHOLD = 10\nawait collection.search(vector=[...], options=VectorSearchOptions(filter=lambda x: x.score > THRESHOLD))  # -> [1309]\n\n# after\nawait collection.search(vector=[...], options=VectorSearchOptions(filter=lambda x: x.score > 10))","handlingStrategy":"validation","validationCode":"import ast\n\ndef has_no_free_names(filter_str: str) -> None:\n    tree = ast.parse(filter_str, mode='eval')\n    assert isinstance(tree.body, ast.Lambda)\n    params = {a.arg for a in tree.body.args.args}\n    allowed_funcs = {'len','str','int','float','bool','abs','min','max','sum','any','all'}\n    for node in ast.walk(tree):\n        if isinstance(node, ast.Name) and node.id not in params and node.id not in allowed_funcs:\n            raise ValueError(f\"filter references non-parameter name '{node.id}'; inline it instead\")","typeGuard":null,"tryCatchPattern":"from semantic_kernel.exceptions import VectorStoreOperationException\ntry:\n    await collection.search(vector=[...], options=opts)\nexcept VectorStoreOperationException as ex:\n    if 'is not allowed in filter expressions' in str(ex) and 'name' in str(ex):\n        # inline the referenced constant and retry\n        ...\n    raise","preventionTips":["Inline constants into the filter body instead of closing over outer variables.","Build filter strings with values interpolated at construction time."],"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"}