microsoft/semantic-kernel · error · VectorStoreOperationException
Function '{func_name}' is not allowed in filter expressions.
Error message
Function '{func_name}' is not allowed in filter expressions. Allowed functions: {', '.join(sorted(self.allowed_filter_functions))} What it means
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.
Source
Thrown at python/semantic_kernel/connectors/in_memory.py:809
f"Use of name '{node.id}' is not allowed in filter expressions. "
f"Only the lambda parameter(s) ({', '.join(lambda_param_names)}) can be used."
)
# For Call nodes, validate that only allowed functions are called
if isinstance(node, ast.Call):
func_name: str
if isinstance(node.func, ast.Name):
func_name = node.func.id
elif isinstance(node.func, ast.Attribute):
func_name = node.func.attr
else:
raise VectorStoreOperationException(
f"Call target node type '{type(node.func).__name__}' is not allowed in filter expressions. "
"Only direct function and method calls are supported."
)
if func_name not in self.allowed_filter_functions:
raise VectorStoreOperationException(
f"Function '{func_name}' is not allowed in filter expressions. "
f"Allowed functions: {', '.join(sorted(self.allowed_filter_functions))}"
)
if (
isinstance(node, (ast.List, ast.Tuple, ast.Set))
and len(node.elts) > self.max_filter_literal_collection_size
):
raise VectorStoreOperationException(
"Collection literals in filter expressions exceed the maximum allowed size."
)
if isinstance(node, ast.Dict) and len(node.keys) > self.max_filter_literal_collection_size:
raise VectorStoreOperationException(
"Collection literals in filter expressions exceed the maximum allowed size."
)
if (View on GitHub (pinned to c028a0c7dc)
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.
Example fix
# before filter = "lambda x: sorted(x.tags) == ['a','b']" # after (use 'in' / allowed ops, or a callable) filter = lambda x: sorted(x.tags) == ['a','b']
Defensive patterns
Strategy: validation
Validate before calling
import ast
ALLOWED = {"len","str","int","float","bool","abs","min","max","sum","any","all",
"lower","upper","strip","startswith","endswith","contains","get","keys","values","items"}
def disallowed_calls(filter_str: str) -> list[str]:
tree = ast.parse(filter_str, mode="eval")
bad = []
for node in ast.walk(tree):
if isinstance(node, ast.Call):
name = node.func.id if isinstance(node.func, ast.Name) else (
node.func.attr if isinstance(node.func, ast.Attribute) else None)
if name not in ALLOWED:
bad.append(name)
return bad Type guard
def is_allowlisted_calls_only(filter_str: str) -> bool:
try:
tree = ast.parse(filter_str, mode="eval")
except SyntaxError:
return False
return all(
(isinstance(n.func, ast.Name) and n.func.id in ALLOWED) or
(isinstance(n.func, ast.Attribute) and n.func.attr in ALLOWED)
for n in ast.walk(tree) if isinstance(n, ast.Call)
) Try / catch
try:
opts = VectorSearchOptions(filter=filter_str)
except VectorStoreOperationException as ex:
if "Function '" in str(ex) and "is not allowed" in str(ex):
# switch to a callable filter that can use arbitrary functions
opts = VectorSearchOptions(filter=lambda x: sorted(x.tags) == ['a']) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Use of name '{node.id}' is not allowed in filter expressions
- Call target node type '{type(node.func).__name__}' is not al
- AST node type '{type(node).__name__}' is not supported durin
- Access to attribute '{node.attr}' is not allowed in filter e
- Access to attribute '{node.attr}' is not allowed in filter e
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/e9f96779b4d4d8b3.
Report an issue: GitHub.