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

  1. Use only the allowed functions/methods shown in the error message; e.g. replace sorted(...) with manual comparisons or filter pre-processing.
  2. Move non-allowlisted logic out of the string filter and into a Python callable passed via options.filter.
  3. If you control the collection class, subclass InMemoryCollection and extend allowed_filter_functions plus direct_filter_functions (only safe, pure functions).
  4. 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

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


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/e9f96779b4d4d8b3. Report an issue: GitHub.