microsoft/semantic-kernel · error · NotImplementedError

Unsupported AST node: {type(node)}

Error message

Unsupported AST node: {type(node)}

What it means

This is the final fallthrough in the MongoDB lambda parser's match statement. After handling Compare, BoolOp, UnaryOp, Attribute, Name, and Constant nodes, any other AST node type reaches this NotImplementedError. It means the filter lambda contains a Python expression construct that the parser cannot translate into a MongoDB query at all — e.g. function calls, list comprehensions, ternary expressions, subscripts, or arithmetic operations.

Source

Thrown at python/semantic_kernel/connectors/mongodb.py:511

                    case ast.UAdd() | ast.USub() | ast.Invert():
                        raise NotImplementedError("Unary +, -, ~ are not supported in MongoDB filters.")
            case ast.Attribute():
                # Only allow attributes that are in the data model
                if node.attr not in self.definition.storage_names:
                    raise VectorStoreOperationException(
                        f"Field '{node.attr}' not in data model (storage property names are used)."
                    )
                return node.attr
            case ast.Name():
                # Only allow names that are in the data model
                if node.id not in self.definition.storage_names:
                    raise VectorStoreOperationException(
                        f"Field '{node.id}' not in data model (storage property names are used)."
                    )
                return node.id
            case ast.Constant():
                return node.value
        raise NotImplementedError(f"Unsupported AST node: {type(node)}")

    @override
    def _get_record_from_result(self, result: dict[str, Any]) -> dict[str, Any]:
        return result

    @override
    def _get_score_from_result(self, result: dict[str, Any]) -> float | None:
        return result.get(MONGODB_SCORE_FIELD)

    @override
    async def __aexit__(self, exc_type, exc_value, traceback) -> None:
        """Exit the context manager."""
        if self.managed_client:
            await self.mongo_client.close()

    async def __aenter__(self) -> Self:
        """Enter the context manager."""
        await self.mongo_client.aconnect()

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Restrict filter lambdas to direct field-vs-value comparisons combined with `and`/`or`/`not`.
  2. Move any computation (function calls, arithmetic, comprehensions) outside the lambda; compute the result and compare the raw field to it.
  3. Replace ternary logic with explicit `and`/`or` boolean combinations of supported comparisons.

Example fix

// before
collection.search(filter=lambda x: len(x.tags) > 0)
// after
# pre-check or restructure; the parser only supports field-level comparisons
collection.search(filter=lambda x: x.tag_count > 0)
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_NODES = (ast.Compare, ast.BoolOp, ast.UnaryOp, ast.Attribute, ast.Name, ast.Constant)
import ast, inspect
def validate_filter_ast(func):
    tree = ast.parse(inspect.getsource(func))
    for node in ast.walk(tree):
        if not isinstance(node, SUPPORTED_NODES) and not isinstance(node, (ast.Lambda, ast.arg, ast.arguments, ast.Load, ast.cmpop, ast.boolop, ast.unaryop, ast.expr_context)):
            raise ValueError(f"Unsupported AST node in filter: {type(node).__name__}")

Try / catch

try:
    results = await collection.search(filter=my_lambda)
except NotImplementedError as e:
    if "Unsupported AST node" in str(e):
        # remove function calls, comprehensions, arithmetic, ternary from the lambda
        ...

Prevention

When it happens

Trigger: A filter lambda uses any unsupported Python expression: function calls (`len(x.field)`), comprehensions (`[v for v in x.items]`), ternary (`a if cond else b`), subscripting (`x.items[0]`), arithmetic (`x.a + x.b`), walrus operators, or lambda definitions inside the filter.

Common situations: Developer embeds business logic (function calls, comprehensions, arithmetic) directly in the filter lambda expecting it to be evaluated, not realizing the parser statically walks the AST rather than executing the lambda.

Related errors


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