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

  1. Flatten to a single MetadataFilters list with one `condition` (all entries combined with the same AND/OR/NOT).
  2. 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.
  3. Emulate nesting by issuing multiple queries and combining results yourself (e.g. run each OR branch, union ids, then apply AND conditions).
  4. 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

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


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/1c464efcd6c7cd77. Report an issue: GitHub.