microsoft/semantic-kernel · error · VectorStoreOperationException
Field '{top_level}' not in data model (storage property name
Error message
Field '{top_level}' not in data model (storage property names are used). What it means
Raised by _parse_attribute_chain when the top-level (outermost) property name in a filter attribute chain is not present in self.definition.storage_names. The connector translates filter lambdas to OData using the storage (serialized) property names of the data model, so a field name not in the model's storage names is rejected with a VectorStoreOperationException before querying the service.
Source
Thrown at python/semantic_kernel/connectors/azure_ai_search.py:653
@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(
left=node.left,
ops=[node.ops[idx]],
comparators=[node.comparators[idx]],
)
)
else:View on GitHub (pinned to c028a0c7dc)
Solutions
- Use only field names that exist in definition.storage_names (the serialized/storage names, not necessarily the Python attribute names).
- If the field has a storage_name alias, reference that storage name in the lambda.
- Add the missing field to the VectorStoreCollectionDefinition if it should be filterable.
Example fix
// before options.filter = lambda x: x.createdAt < 5 # Python name, but storage_name is 'created_at' // after options.filter = lambda x: x.created_at < 5
Defensive patterns
Strategy: validation
Validate before calling
def validate_filter_fields_against_model(filter_lambda, definition) -> None:
import ast
src = ast.getsource(filter_lambda)
tree = ast.parse(src.strip() if src.startswith("lambda") else src, mode="exec")
for node in ast.walk(tree):
if isinstance(node, ast.Attribute):
chain = node
while isinstance(chain, ast.Attribute):
chain = chain.value
# top-level attr is node.attr when chain rooted at Name
top = node.attr
if isinstance(node.value, ast.Name):
assert top in definition.storage_names, (
f"Filter field '{top}' not in model storage_names {set(definition.storage_names)}"
)
validate_filter_fields_against_model(opts.filter, collection.definition) Try / catch
from semantic_kernel.exceptions import VectorStoreOperationException
try:
res = await collection.search(values=q, options=opts)
except VectorStoreOperationException as e:
if "not in data model" in str(e):
opts.filter = lambda x: x.created_at < 5 # use correct storage_name
res = await collection.search(values=q, options=opts)
raise Prevention
- Reference storage_names (serialized names) in filter lambdas, not Python attribute names when they differ.
- Validate filter field names against definition.storage_names before searching.
- Add the field to the definition if it should be filterable.
When it happens
Trigger: Writing a filter lambda like lambda x: x.nonexistent_field == 1, or using the Python property name when the field has a different storage_name (the serialized name). The check is against storage_names, not the Python attribute names.
Common situations: Typos in field names; using the Python attribute name instead of the storage_name when they differ; referencing a field that was removed from the model; filtering on a field that exists only in the index but not in the VectorStoreCollectionDefinition.
Related errors
- Unsupported attribute chain root: {type(current)}
- 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)}
AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13).
Data as JSON: /api/errors/ce8786ae285e6ed3.
Report an issue: GitHub.