{"record":{"id":"e9f96779b4d4d8b3","repo":"microsoft/semantic-kernel","slug":"function-func-name-is-not-allowed-in-filter-ex","errorCode":null,"errorMessage":"Function '{func_name}' is not allowed in filter expressions. Allowed functions: {', '.join(sorted(self.allowed_filter_functions))}","messagePattern":"Function '(.+?)' is not allowed in filter expressions\\. Allowed functions: (.+?)","errorType":"validation","errorClass":"VectorStoreOperationException","httpStatus":null,"severity":"error","filePath":"python/semantic_kernel/connectors/in_memory.py","lineNumber":809,"sourceCode":"                    f\"Use of name '{node.id}' is not allowed in filter expressions. \"\n                    f\"Only the lambda parameter(s) ({', '.join(lambda_param_names)}) can be used.\"\n                )\n\n            # For Call nodes, validate that only allowed functions are called\n            if isinstance(node, ast.Call):\n                func_name: str\n                if isinstance(node.func, ast.Name):\n                    func_name = node.func.id\n                elif isinstance(node.func, ast.Attribute):\n                    func_name = node.func.attr\n                else:\n                    raise VectorStoreOperationException(\n                        f\"Call target node type '{type(node.func).__name__}' is not allowed in filter expressions. \"\n                        \"Only direct function and method calls are supported.\"\n                    )\n\n                if func_name not in self.allowed_filter_functions:\n                    raise VectorStoreOperationException(\n                        f\"Function '{func_name}' is not allowed in filter expressions. \"\n                        f\"Allowed functions: {', '.join(sorted(self.allowed_filter_functions))}\"\n                    )\n\n            if (\n                isinstance(node, (ast.List, ast.Tuple, ast.Set))\n                and len(node.elts) > self.max_filter_literal_collection_size\n            ):\n                raise VectorStoreOperationException(\n                    \"Collection literals in filter expressions exceed the maximum allowed size.\"\n                )\n\n            if isinstance(node, ast.Dict) and len(node.keys) > self.max_filter_literal_collection_size:\n                raise VectorStoreOperationException(\n                    \"Collection literals in filter expressions exceed the maximum allowed size.\"\n                )\n\n            if (","sourceCodeStart":791,"sourceCodeEnd":827,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/semantic_kernel/connectors/in_memory.py#L791-L827","documentation":"Thrown by InMemoryCollection._parse_and_validate_filter (in_memory.py:809) when a Call or method-call name is not in the class attribute allowed_filter_functions (in_memory.py:477). The allowlist is intentionally small: len, str, int, float, bool, abs, min, max, sum, any, all, lower, upper, strip, startswith, endswith, contains, get, keys, values, items. The message lists every permitted name so the caller can correct the expression.","triggerScenarios":"Calling a builtin or method not on the allowlist, e.g. \"lambda x: sorted(x.tags)\", \"lambda x: x.name.replace('a','b')\", or \"lambda x: list(x.keys())\". The func_name extracted at in_memory.py:798-801 is matched against allowed_filter_functions at in_memory.py:808.","commonSituations":"Assuming normal Python builtins are available; using string methods beyond lower/upper/strip/startswith/endswith/contains; calling collection constructors like list/set/dict; migrating a filter that relied on a richer API.","solutions":["Use only the allowed functions/methods shown in the error message; e.g. replace sorted(...) with manual comparisons or filter pre-processing.","Move non-allowlisted logic out of the string filter and into a Python callable passed via options.filter.","If you control the collection class, subclass InMemoryCollection and extend allowed_filter_functions plus direct_filter_functions (only safe, pure functions).","Re-read the message: it prints the exact sorted allowlist to compare against."],"exampleFix":"# before\nfilter = \"lambda x: sorted(x.tags) == ['a','b']\"\n\n# after (use 'in' / allowed ops, or a callable)\nfilter = lambda x: sorted(x.tags) == ['a','b']","handlingStrategy":"validation","validationCode":"import ast\n\nALLOWED = {\"len\",\"str\",\"int\",\"float\",\"bool\",\"abs\",\"min\",\"max\",\"sum\",\"any\",\"all\",\n           \"lower\",\"upper\",\"strip\",\"startswith\",\"endswith\",\"contains\",\"get\",\"keys\",\"values\",\"items\"}\n\ndef disallowed_calls(filter_str: str) -> list[str]:\n    tree = ast.parse(filter_str, mode=\"eval\")\n    bad = []\n    for node in ast.walk(tree):\n        if isinstance(node, ast.Call):\n            name = node.func.id if isinstance(node.func, ast.Name) else (\n                node.func.attr if isinstance(node.func, ast.Attribute) else None)\n            if name not in ALLOWED:\n                bad.append(name)\n    return bad","typeGuard":"def is_allowlisted_calls_only(filter_str: str) -> bool:\n    try:\n        tree = ast.parse(filter_str, mode=\"eval\")\n    except SyntaxError:\n        return False\n    return all(\n        (isinstance(n.func, ast.Name) and n.func.id in ALLOWED) or\n        (isinstance(n.func, ast.Attribute) and n.func.attr in ALLOWED)\n        for n in ast.walk(tree) if isinstance(n, ast.Call)\n    )","tryCatchPattern":"try:\n    opts = VectorSearchOptions(filter=filter_str)\nexcept VectorStoreOperationException as ex:\n    if \"Function '\" in str(ex) and \"is not allowed\" in str(ex):\n        # switch to a callable filter that can use arbitrary functions\n        opts = VectorSearchOptions(filter=lambda x: sorted(x.tags) == ['a'])","preventionTips":["Read the error message: it prints the exact allowlist to compare against.","For richer logic, pass a Python callable in options.filter instead of a string.","If you must extend the allowlist, subclass InMemoryCollection and add only pure, side-effect-free functions.","Never add open/eval/exec/import or IO functions to the allowlist."],"tags":["in-memory-collection","filter","sandbox","allowlist","function-calls"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}