microsoft/semantic-kernel · error · NotImplementedError

Unsupported operator: {type(op)}

Error message

Unsupported operator: {type(op)}

What it means

Raised at the end of the ast.Compare branch in _lambda_parser when the comparison operator is not one of the handled cases (In, NotIn, Eq, NotEq, Gt, GtE, Lt, LtE). Any other operator that Python can syntactically place in a comparison falls through to NotImplementedError. The OData filter language only supports a subset of Python's comparison operators.

Source

Thrown at python/semantic_kernel/connectors/azure_ai_search.py:700

                op = node.ops[0]
                match op:
                    case ast.In():
                        return f"search.ismatch({left}, '{right}')"
                    case ast.NotIn():
                        return f"not search.ismatch({left}, '{right}')"
                    case ast.Eq():
                        return f"{left} eq {right}"
                    case ast.NotEq():
                        return f"{left} ne {right}"
                    case ast.Gt():
                        return f"{left} gt {right}"
                    case ast.GtE():
                        return f"{left} ge {right}"
                    case ast.Lt():
                        return f"{left} lt {right}"
                    case ast.LtE():
                        return f"{left} le {right}"
                raise NotImplementedError(f"Unsupported operator: {type(op)}")
            case ast.BoolOp():
                op_str = "and" if isinstance(node.op, ast.And) else "or"
                return "(" + f" {op_str} ".join([self._lambda_parser(v) for v in node.values]) + ")"
            case ast.UnaryOp():
                match node.op:
                    case ast.UAdd():
                        return f"+{self._lambda_parser(node.operand)}"
                    case ast.USub():
                        return f"-{self._lambda_parser(node.operand)}"
                    case ast.Invert():
                        raise NotImplementedError("Invert operation is not supported.")
                    case ast.Not():
                        return f"not {self._lambda_parser(node.operand)}"
            case ast.Attribute():
                # Support nested property chains
                return _parse_attribute_chain(node)
            case ast.Name():
                raise NotImplementedError("Constants are not supported, make sure to use a value or a attribute.")

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Replace 'is'/'is not' comparisons with == / != (e.g. lambda x: x.field == None).
  2. Stick to the supported operators: ==, !=, >, >=, <, <=, in, not in.
  3. For null checks use == None / != None, which the parser maps to 'eq null'/'ne null'.

Example fix

// before
options.filter = lambda x: x.deleted is True

// after
options.filter = lambda x: x.deleted == True
Defensive patterns

Strategy: validation

Validate before calling

import ast

def filter_uses_supported_ops(filter_lambda) -> None:
    supported = {ast.Eq, ast.NotEq, ast.Gt, ast.GtE, ast.Lt, ast.LtE, ast.In, ast.NotIn}
    tree = ast.parse(ast.getsource(filter_lambda), mode="exec")
    for node in ast.walk(tree):
        if isinstance(node, ast.Compare):
            for op in node.ops:
                assert type(op) in supported, f"Unsupported comparison operator: {type(op).__name__}"

filter_uses_supported_ops(opts.filter)

Try / catch

try:
    res = await collection.search(values=q, options=opts)
except NotImplementedError as e:
    if "Unsupported operator" in str(e):
        opts.filter = lambda x: x.field == None  # replace 'is None'
        res = await collection.search(values=q, options=opts)
    raise

Prevention

When it happens

Trigger: Using 'is' or 'is not' in a filter lambda (e.g. lambda x: x.field is None), which produce ast.Is/ast.IsNot operators that are not mapped. Also theoretically any exotic comparison operator the parser does not handle.

Common situations: Writing lambda x: x.field is None or lambda x: x.field is not None instead of == None / != None; idiomatic Python 'is None' checks copied into a filter expression.

Related errors


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