microsoft/semantic-kernel · error · NotImplementedError

Only == comparisons are supported.

Error message

Only == comparisons are supported.

What it means

The visitor supports only a single equality operator (ast.Eq). A Compare node whose ops are not exactly one `==` raises NotImplementedError. Any other operator (!=, <, >, <=, >=, in, is) or chained comparisons are rejected.

Source

Thrown at python/semantic_kernel/connectors/_search_shared.py:33

    """Visitor to parse a lambda function for Brave and Google Search filters."""

    def __init__(self, valid_parameters: list[str]):
        """Initialize the visitor with a list of valid parameters."""
        self.filters: list[dict[str, str]] = []
        self.valid_parameters = valid_parameters

    @override
    def visit_Lambda(self, node):
        self.visit(node.body)

    @override
    def visit_Compare(self, node):
        # Only support x.FIELD == VALUE
        if not (isinstance(node.left, ast.Attribute) and isinstance(node.left.value, ast.Name)):
            raise NotImplementedError("Left side must be x.FIELD.")
        field = node.left.attr
        if not (len(node.ops) == 1 and isinstance(node.ops[0], ast.Eq)):
            raise NotImplementedError("Only == comparisons are supported.")
        right = node.comparators[0]
        if isinstance(right, ast.Constant):
            if right.value is None:
                raise NotImplementedError("None values are not supported.")
            value = str(right.value)
        else:
            raise NotImplementedError("Only constant values are supported on the right side.")
        if field not in self.valid_parameters:
            raise ValueError(f"Field '{field}' is not supported.")
        self.filters.append({field: quote_plus(value)})

    @override
    def visit_BoolOp(self, node):
        if not isinstance(node.op, ast.And):
            raise NotImplementedError("Only 'and' of == comparisons is supported.")
        for v in node.values:
            self.visit(v)

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Express the filter as a single `==` equality (`lambda x: x.field == "v"`).
  2. For multi-value matching, combine several `x.field == v` clauses with `and` (see BoolOp support) rather than `in`.

Example fix

// before
lambda x: x.category != "ads"
lambda x: x.region in ("us", "eu")

// after
lambda x: x.category == "news"
# membership must be expressed via explicit equality (no 'in' support)
Defensive patterns

Strategy: validation

Validate before calling

import ast
node = ast.parse(filter_src, mode='eval').body
def check_eq(n):
    if isinstance(n, ast.Compare):
        assert len(n.ops) == 1 and isinstance(n.ops[0], ast.Eq), 'only == supported'
    if isinstance(n, ast.BoolOp):
        for v in n.values: check_eq(v)
check_eq(node.body)

Type guard

def is_single_eq(node: ast.Compare) -> bool:
    return len(node.ops) == 1 and isinstance(node.ops[0], ast.Eq)

Prevention

When it happens

Trigger: Using an inequality or membership test in the filter lambda: `lambda x: x.field != "v"`, `lambda x: x.field in (...)`, `lambda x: x.field > 5`, or a chained comparison `lambda x: 1 == x.field == 1`.

Common situations: Assuming range or membership filters are supported; copying OData-style filter syntax into the lambda.

Related errors


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