run-llama/llama_index · error · ValueError
Nested MetadataFilters are not supported.
Error message
Nested MetadataFilters are not supported.
What it means
`build_metadata_filter_fn` iterates the entries of a MetadataFilters object and can compose multiple conditions via `condition` (AND/OR/NOT), but it cannot recursively evaluate another MetadataFilters nested inside `filters=[...]`. Nesting is detected with an isinstance check and raises ValueError immediately, before any metadata is evaluated. Use the single-level list plus the condition field, or a store with native nested-filter support.
Source
Thrown at llama-index-core/llama_index/core/vector_stores/utils.py:164
if isinstance(value, str) and isinstance(metadata_value, str):
return value.lower() in metadata_value.lower()
raise TypeError(
"Both metadata_value and value should be strings to be used with a "
"TEXT_MATCH_INSENSITIVE filter"
)
if operator == FilterOperator.ALL:
return all(val in metadata_value for val in value)
if operator == FilterOperator.ANY:
return any(val in metadata_value for val in value)
raise ValueError(f"Invalid operator: {operator}")
metadata = metadata_lookup_fn(node_id)
filter_matches_list = []
for filter_ in filter_list:
if isinstance(filter_, MetadataFilters):
raise ValueError("Nested MetadataFilters are not supported.")
filter_matches = True
metadata_value = metadata.get(filter_.key, None)
if filter_.operator == FilterOperator.IS_EMPTY:
filter_matches = (
metadata_value is None
or metadata_value == ""
or metadata_value == []
)
else:
filter_matches = _process_filter_match(
operator=filter_.operator,
value=filter_.value,
metadata_value=metadata_value,
)
filter_matches_list.append(filter_matches)
View on GitHub (pinned to afd0fef371)
Solutions
- Flatten to a single MetadataFilters list with one `condition` (all entries combined with the same AND/OR/NOT).
- If you truly need nested boolean logic, use a vector store whose native filtering supports it and pass MetadataFilters through that store's query path.
- Emulate nesting by issuing multiple queries and combining results yourself (e.g. run each OR branch, union ids, then apply AND conditions).
- Validate your filter structure (no isinstance(entry, MetadataFilters)) before querying.
Example fix
# before
f = MetadataFilters(
filters=[MetadataFilters(filters=[MetadataFilter("a", 1), MetadataFilter("b", 2)], condition=FilterCondition.OR)],
condition=FilterCondition.AND,
)
# after (single level, one condition)
f = MetadataFilters(
filters=[MetadataFilter("a", 1), MetadataFilter("b", 2)],
condition=FilterCondition.OR,
) Defensive patterns
Strategy: validation
Validate before calling
from llama_index.core.vector_stores.types import MetadataFilters
def filters_not_nested(filters: MetadataFilters) -> bool:
return not any(isinstance(f, MetadataFilters) for f in filters.filters) Try / catch
try:
result = store.query(query)
except ValueError as e:
if "Nested MetadataFilters" in str(e):
raise ValueError("flatten filters or use a store with native nested filtering") from e
raise Prevention
- Keep filter lists flat with a single condition for client-side-filtering stores.
- Validate LLM-generated filter JSON against a schema that forbids nesting.
- Emulate AND-of-OR with multiple queries and set operations on ids.
When it happens
Trigger: Constructing `MetadataFilters(filters=[MetadataFilters(filters=[...], condition=FilterCondition.OR)], condition=FilterCondition.AND)` — i.e. AND-of-ORs — and querying a store that filters client-side through build_metadata_filter_fn (SimpleVectorStore and similar).
Common situations: Porting boolean filter trees from Pinecone/Qdrant/Weaviate examples into stores without nested-filter support; building advanced faceted search that needs grouped boolean logic; LLM-generated filter JSON that naturally nests groups.
Related errors
- Cannot filter stores that were persisted without metadata. P
- Invalid query mode: {query.mode}
- Vector Store only supports exact match filters. Please use E
- Both metadata_value and value should be strings to be used w
- Both metadata_value and value should be strings to be used w
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/1c464efcd6c7cd77.
Report an issue: GitHub.