microsoft/semantic-kernel · error · NotImplementedError

Constants or variables are not supported, use a value or att

Error message

Constants or variables are not supported, use a value or attribute.

What it means

The AST translator rejects bare names (ast.Name nodes) entirely with NotImplementedError. In a filter lambda, a bare Name is a variable/identifier reference (e.g. an unquoted parameter, an imported constant, or the lambda parameter used on the value side), none of which Cosmos SQL parameter binding supports in this design. Only attribute accesses (c.field) and literal constants are allowed.

Source

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

                        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(
                            f"Field '{node.attr}' not in data model (storage property names are used)."
                        )
                    return f"c.{node.attr}"
                case ast.Name():
                    # Could be a variable or constant; not supported
                    raise NotImplementedError("Constants or variables are not supported, use a value or attribute.")
                case ast.Constant():
                    # Bind strings as query parameters to avoid SQL injection. Numbers and null
                    # cannot carry injection, so they are inlined.
                    if isinstance(node.value, str):
                        name = f"@filter_p{len(parameters)}"
                        parameters.append({"name": name, "value": node.value})
                        return name
                    if isinstance(node.value, (float, int)):
                        return str(node.value)
                    if node.value is None:
                        return "null"
                    raise NotImplementedError(f"Unsupported constant type: {type(node.value)}")
            raise NotImplementedError(f"Unsupported AST node: {type(node)}")

        return parse(node), parameters

    @override
    def _get_record_from_result(self, result: dict[str, Any]) -> dict[str, Any]:

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Inline literal values in the filter lambda (e.g. x.category == "news") instead of referencing outer variables; the constant gets bound as a query parameter automatically.
  2. If you must parameterize, construct the lambda with the literal value substituted in (e.g. via a default argument: lambda x, v=category: x.category == v) — verify the AST still resolves to a Constant, or refactor to build the filter another way.
  3. Ensure attribute accesses appear on the model side and constants on the value side of comparisons.

Example fix

// before
cat = "news"
options = VectorSearchOptions(filter=lambda x: x.category == cat)  # cat is an ast.Name
// after
options = VectorSearchOptions(filter=lambda x: x.category == "news")  # literal Constant
Defensive patterns

Strategy: validation

Validate before calling

import ast
tree = ast.parse(filter_src, mode="eval")
for node in ast.walk(tree):
    if isinstance(node, ast.Name):
        raise ValueError("Filter contains a bare variable/constant reference; inline literal values")

Type guard

def has_no_bare_name(node: ast.AST) -> bool:
    return not any(isinstance(n, ast.Name) for n in ast.walk(node))

Prevention

When it happens

Trigger: Writing a filter lambda where the value side is a bare identifier instead of a literal, e.g. lambda x: x.category == CATEGORY where CATEGORY is an outer variable, or referencing the lambda parameter incorrectly. Such nodes compile to ast.Name and hit azure_cosmos_db.py:953-955.

Common situations: Capturing an outer-scope variable in the lambda (closure) rather than inlining its literal value; or writing the comparison operands in the wrong order so a name appears where a constant is expected.

Related errors


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