microsoft/semantic-kernel · error · NotImplementedError
Unsupported attribute chain root: {type(current)}
Error message
Unsupported attribute chain root: {type(current)} What it means
Raised inside _lambda_parser._parse_attribute_chain when the root of an attribute chain is not an ast.Name node. The parser walks a chain like x.a.b by following .value until it reaches the root; it expects that root to be an ast.Name (the lambda parameter, e.g. 'x'). If the chain is rooted on a call, subscript, constant, or any other expression, it cannot produce a valid OData field path and raises NotImplementedError.
Source
Thrown at python/semantic_kernel/connectors/azure_ai_search.py:647
raise VectorSearchExecutionException("Failed to search the collection.") from exc
return KernelSearchResults(
results=self._get_vector_search_results_from_results(raw_results, options),
total_count=await raw_results.get_count() if options.include_total_count else None,
)
@override
def _lambda_parser(self, node: ast.AST) -> Any:
def _parse_attribute_chain(attr_node: ast.Attribute) -> str:
parts = []
current = attr_node
while isinstance(current, ast.Attribute):
parts.append(current.attr)
current = current.value # type: ignore
if isinstance(current, ast.Name):
# skip the root variable name (e.g., 'x')
pass
else:
raise NotImplementedError(f"Unsupported attribute chain root: {type(current)}")
# reverse to get the correct order
prop_path = "/".join(reversed(parts))
# Check if the top-level property is in the data model
top_level = parts[-1] if parts else None
if top_level and top_level not in self.definition.storage_names:
raise VectorStoreOperationException(
f"Field '{top_level}' not in data model (storage property names are used)."
)
return prop_path
match node:
case ast.Compare():
if len(node.ops) > 1:
values: list[ast.expr] = []
for idx in range(len(node.ops)):
if idx == 0:
values.append(
ast.Compare(View on GitHub (pinned to c028a0c7dc)
Solutions
- Make sure every attribute chain in the filter lambda starts at the lambda parameter (e.g. lambda x: x.field == value).
- Avoid calling functions or subscripting at the root of a field reference in the filter.
- If you need a constant from outer scope, bind it as the comparator (right-hand side), not as part of the field path.
Example fix
// before options.filter = lambda x: helper.x.field == 1 # root is 'helper', not a Name // after options.filter = lambda x: x.field == 1
Defensive patterns
Strategy: validation
Validate before calling
import ast
def filter_lambdas_root_in_name(func):
tree = ast.parse(ast.unparse(ast.fix_missing_locations(
ast.parse("lambda x: None", mode="eval").body.replace(body=...)
))) if False else None
# simpler: static lint that attribute chains in the lambda start at the lambda param
src = ast.unparse(ast.parse(ast.getsource(func.__code__), mode="exec"))
return src # review manually; chains must start at the param name
# Enforce convention: all filter lambdas start chains at the lambda parameter Try / catch
from semantic_kernel.exceptions import VectorStoreException
try:
res = await collection.search(values=q, options=opts_with_filter)
except NotImplementedError as e:
if "Unsupported attribute chain root" in str(e):
opts.filter = lambda x: x.field == value # rewrite rooted at x
res = await collection.search(values=q, options=opts)
raise Prevention
- Root every attribute chain in a filter lambda at the lambda parameter (x.field, not obj.field).
- Do not call functions or subscript at the base of a field reference in filters.
- Keep filters simple: x.field <op> constant.
When it happens
Trigger: Writing a filter lambda whose left-hand attribute access is rooted on something other than the lambda variable — e.g. lambda x: some_obj.field == 1, lambda x: get(x).field == 1, or lambda x: x.items[0].field == 1 (subscript root). The parser only supports chains beginning at the lambda parameter name.
Common situations: Referencing a module-level or outer-scope object inside a filter lambda instead of the record parameter; chaining off a method call; using subscript indexing at the base of an attribute chain.
Related errors
- Unsupported operator: {type(op)}
- Invert operation is not supported.
- 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/022c83ff5d53f002.
Report an issue: GitHub.