microsoft/semantic-kernel · error · NotImplementedError

Invert operation is not supported.

Error message

Invert operation is not supported.

What it means

Raised in the ast.UnaryOp branch of _lambda_parser when the unary operator is ast.Invert (the Python bitwise NOT, ~). Azure AI Search's OData filter expression language has no bitwise-invert equivalent, so the parser explicitly rejects it with NotImplementedError rather than producing a meaningless query.

Source

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

                        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.")
            case ast.Constant():
                value = node.value
                if isinstance(value, str):
                    return "'" + value.replace("'", "''") + "'"
                if isinstance(value, bytes):
                    return "'" + value.decode("utf-8").replace("'", "''") + "'"
                if isinstance(value, bool):
                    return str(value).lower()
                if value is None:
                    return "null"
                if isinstance(value, (int, float)):

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Remove the ~ operator from filter lambdas; OData filters do not support bitwise inversion.
  2. If you need bitmask semantics, precompute the inverted value and compare with == / != against the field.
  3. Use 'not' (logical) instead of '~' (bitwise) if you intended logical negation of a boolean.

Example fix

// before
options.filter = lambda x: ~x.flag == -2

// after
options.filter = lambda x: x.flag == 1   # precomputed value, no ~
Defensive patterns

Strategy: validation

Validate before calling

import ast

def filter_has_no_invert(filter_lambda) -> None:
    tree = ast.parse(ast.getsource(filter_lambda), mode="exec")
    for node in ast.walk(tree):
        assert not (isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.Invert)), \
            "Bitwise invert (~) is not supported in OData filters"

filter_has_no_invert(opts.filter)

Try / catch

try:
    res = await collection.search(values=q, options=opts)
except NotImplementedError as e:
    if "Invert operation is not supported" in str(e):
        opts.filter = lambda x: x.flag == 1  # precomputed, no ~
        res = await collection.search(values=q, options=opts)
    raise

Prevention

When it happens

Trigger: Using the ~ operator in a filter lambda, e.g. lambda x: ~x.flag == -2, or ~ applied to a field/operand anywhere in the filter expression.

Common situations: Accidentally using ~ (bitwise not) when ~ was meant on a non-filter object; copy-pasting numeric/bitmask logic into a vector-store filter.

Related errors


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