microsoft/semantic-kernel · error · VectorStoreOperationException

Filter string is not valid Python: {e}

Error message

Filter string is not valid Python: {e}

What it means

Thrown by _parse_and_validate_filter (in_memory.py:755-756) when ast.parse(filter_str, mode='eval') raises SyntaxError. The filter string is not syntactically valid Python.

Source

Thrown at python/semantic_kernel/connectors/in_memory.py:756

            for filter in callable_filters:
                if self._run_filter(filter, record):
                    filtered_records[key] = record
        return filtered_records

    def _parse_and_validate_filter(self, filter_str: str) -> Callable:
        """Parse and validate a string filter as a lambda expression, then return the callable.

        Uses an allowlist approach - only explicitly permitted AST node types and function names
        are allowed. This can be customized by overriding `allowed_filter_ast_nodes` and
        `allowed_filter_functions` class attributes.
        """
        if len(filter_str) > self.max_filter_source_length:
            raise VectorStoreOperationException("Filter string exceeds the maximum allowed length.")

        try:
            tree = ast.parse(filter_str, mode="eval")
        except SyntaxError as e:
            raise VectorStoreOperationException(f"Filter string is not valid Python: {e}") from e

        # Only allow lambda expressions at the top level
        if not (isinstance(tree, ast.Expression) and isinstance(tree.body, ast.Lambda)):
            raise VectorStoreOperationException(
                "Filter string must be a lambda expression, e.g. 'lambda x: x.key == 1'"
            )

        # Get the lambda parameter name(s) to allow them as valid Name nodes
        lambda_node = tree.body
        lambda_param_names = {arg.arg for arg in lambda_node.args.args}
        lambda_param_order = [arg.arg for arg in lambda_node.args.args]
        # Walk the AST to validate all nodes against the allowlist
        for node_count, node in enumerate(ast.walk(tree), start=1):
            if node_count > self.max_filter_ast_node_count:
                raise VectorStoreOperationException("Filter expression exceeds the maximum allowed complexity.")

            node_type = type(node)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Fix the Python syntax of the lambda.
  2. Test the lambda body in a Python REPL or with ast.parse before passing it.
  3. If generating filters dynamically, compile/parse them during construction to fail fast.

Example fix

# before
VectorSearchOptions(filter="lambda x: x.id ==")   # incomplete expression
# after
VectorSearchOptions(filter="lambda x: x.id == 1")
Defensive patterns

Strategy: validation

Validate before calling

import ast
def is_valid_python(expr: str) -> bool:
    try:
        ast.parse(expr, mode="eval")
        return True
    except SyntaxError:
        return False

Try / catch

try:
    results = await collection.search(search_type=SearchType.VECTOR, options=opts)
except VectorStoreOperationException as e:
    logger.warning("filter rejected: %s", e.__cause__ or e)
    results = None

Prevention

When it happens

Trigger: A lambda with a syntax error: unbalanced parentheses, a trailing operator, an incomplete expression, stray characters, or invalid keyword usage.

Common situations: Hand-writing filter strings; templating filters with f-strings that produce malformed output; truncation of a filter in transit.

Related errors


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