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
- Remove the ~ operator from filter lambdas; OData filters do not support bitwise inversion.
- If you need bitmask semantics, precompute the inverted value and compare with == / != against the field.
- 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
- Never use ~ in filter lambdas; OData has no bitwise invert.
- Use 'not' for logical negation, and precompute inverted numeric values.
- Lint filters for ast.Invert before passing them to search.
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
- Unsupported attribute chain root: {type(current)}
- Unsupported operator: {type(op)}
- Constants are not supported, make sure to use a value or a a
- Unsupported constant type: {type(value)}
- Field '{top_level}' not in data model (storage property name
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/0bbb9fe312fbdd18.
Report an issue: GitHub.