microsoft/semantic-kernel · error · NotImplementedError

Unsupported operator: {type(op)}

Error message

Unsupported operator: {type(op)}

What it means

The connector translates Python filter lambdas into Cosmos SQL by walking the AST. Inside a comparison node it only maps a fixed set of operators (In, NotIn, Eq, NotEq, Gt, GtE, Lt, LtE). Any comparison operator not in that set reaches the trailing raise NotImplementedError. This means the filter expression used a Python comparison that the translator was never taught to render as SQL.

Source

Thrown at python/semantic_kernel/connectors/azure_cosmos_db.py:931

                    match op:
                        case ast.In():
                            # Cosmos DB: ARRAY_CONTAINS(right, left)
                            return f"ARRAY_CONTAINS({right}, {left})"
                        case ast.NotIn():
                            return f"NOT ARRAY_CONTAINS({right}, {left})"
                        case ast.Eq():
                            return f"{left} = {right}"
                        case ast.NotEq():
                            return f"{left} != {right}"
                        case ast.Gt():
                            return f"{left} > {right}"
                        case ast.GtE():
                            return f"{left} >= {right}"
                        case ast.Lt():
                            return f"{left} < {right}"
                        case ast.LtE():
                            return f"{left} <= {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([parse(v) for v in node.values]) + ")"
                case ast.UnaryOp():
                    match node.op:
                        case ast.Not():
                            return f"NOT ({parse(node.operand)})"
                        case ast.UAdd():
                            return f"+{parse(node.operand)}"
                        case ast.USub():
                            return f"-{parse(node.operand)}"
                        case ast.Invert():
                            raise NotImplementedError("Invert operation is not supported.")
                    raise NotImplementedError(f"Unsupported unary operator: {type(node.op)}")
                case ast.Attribute():
                    # Cosmos DB: c.field_name
                    if node.attr not in self.definition.storage_names:
                        raise VectorStoreOperationException(

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Replace 'is'/'is not' comparisons with '=='/'!=' in the filter lambda so they compile to ast.Eq / ast.NotEq, which the translator supports.
  2. Restrict filters to the supported operator set (==, !=, <, >, <=, >=, in, not in) and the supported logical/unary ops.
  3. For null checks use == None / != None rather than is None / is not None.

Example fix

// before
options = VectorSearchOptions(filter=lambda x: x.category is None)
// after
options = VectorSearchOptions(filter=lambda x: x.category == None)
Defensive patterns

Strategy: validation

Validate before calling

import ast
SUPPORTED_OPS = (ast.Eq, ast.NotEq, ast.Gt, ast.GtE, ast.Lt, ast.LtE, ast.In, ast.NotIn)
tree = ast.parse(filter_src, mode="eval")
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"Filter uses unsupported operator: {type(op).__name__}")

Type guard

def is_supported_filter_op(node: ast.Compare) -> bool:
    ok = (ast.Eq, ast.NotEq, ast.Gt, ast.GtE, ast.Lt, ast.LtE, ast.In, ast.NotIn)
    return all(isinstance(op, ok) for op in node.ops)

Prevention

When it happens

Trigger: Writing a filter lambda using an unsupported comparison operator, most commonly identity checks (a is b / a is not b, i.e. ast.Is / ast.IsNot) which Python emits for the 'is' keyword. The AST visitor's Compare branch has no case for them.

Common situations: A developer writes lambda x: x.category is None or x.tag is sentinel in a VectorSearchOptions.filter, expecting equality semantics; 'is' compiles to ast.Is, which is unsupported, whereas == compiles to ast.Eq and would work.

Related errors


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