microsoft/semantic-kernel · error · NotImplementedError

Unsupported operator: {type(op)}

Error message

Unsupported operator: {type(op)}

What it means

The MongoDB Atlas collection filter parser walks the AST of a lambda predicate and translates Python comparison operators into MongoDB query operators. This NotImplementedError fires when the lambda contains a comparison operator that the parser has no mapping for — currently only In, NotIn, Eq, NotEq, Gt, GtE, Lt, LtE are handled. Any other ast.cmpop subclass (e.g. Is, IsNot, IsInstance patterns) falls through all match cases and reaches the raise.

Source

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

                match op:
                    case ast.In():
                        return {left: {"$in": right}}
                    case ast.NotIn():
                        return {left: {"$nin": right}}
                    case ast.Eq():
                        # MongoDB allows short form: {field: value}
                        return {left: right}
                    case ast.NotEq():
                        return {left: {"$ne": right}}
                    case ast.Gt():
                        return {left: {"$gt": right}}
                    case ast.GtE():
                        return {left: {"$gte": right}}
                    case ast.Lt():
                        return {left: {"$lt": right}}
                    case ast.LtE():
                        return {left: {"$lte": right}}
                raise NotImplementedError(f"Unsupported operator: {type(op)}")
            case ast.BoolOp():
                op = node.op  # type: ignore
                values = [self._lambda_parser(v) for v in node.values]
                if isinstance(op, ast.And):
                    return {"$and": values}
                if isinstance(op, ast.Or):
                    return {"$or": values}
                raise NotImplementedError(f"Unsupported BoolOp: {type(op)}")
            case ast.UnaryOp():
                match node.op:
                    case ast.Not():
                        operand = self._lambda_parser(node.operand)
                        return {"$not": operand}
                    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:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Rewrite the filter lambda to use only supported operators: ==, !=, >, >=, <, <=, `in`, `not in`.
  2. Replace any `x is None` with `x == None` (or better, restructure the filter to avoid null checks the parser cannot express).
  3. If you need a condition the parser does not support, pre-filter results in application code after the query instead of inside the lambda.

Example fix

// before
collection.search(filter=lambda x: x.status is not None)
// after
collection.search(filter=lambda x: x.status != None)
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_OPS = (ast.Eq, ast.NotEq, ast.Gt, ast.GtE, ast.Lt, ast.LtE, ast.In, ast.NotIn)
import ast
def validate_filter_lambda(func):
    tree = ast.parse(inspect.getsource(func))
    for node in ast.walk(tree):
        if isinstance(node, ast.Compare):
            for op in node.ops:
                if not isinstance(op, SUPPORTED_OPS):
                    raise ValueError(f"Unsupported comparison operator: {type(op).__name__}")

Try / catch

try:
    results = await collection.search(filter=my_lambda)
except NotImplementedError as e:
    if "Unsupported operator" in str(e):
        # rewrite the filter using only ==, !=, >, >=, <, <=, in, not in
        ...

Prevention

When it happens

Trigger: Calling a collection search/get with a lambda filter that uses identity comparison (`x is y`, `x is not y`) or any operator outside the eight supported cmpop types. For example `lambda x: x.field Is None`-style logic, or using `is`/`is not` inside the predicate passed to the vector store collection.

Common situations: Developer writes a filter lambda using Python identity operators (`is`, `is not`) thinking they behave like equality. Developer uses comparison against `None` with `is` instead of `==`. Migrating from a SQL or ORM filter that supports richer operators.

Related errors


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