llamaIndex - 💡(How to fix) Fix [Bug]: MetadataFilter NE/NIN silently exclude nodes that are missing the filtered key [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Fix Action

Fixed

Code Example

if metadata_value is None:
    return False

---

from llama_index.core.vector_stores.types import (
    FilterCondition,
    FilterOperator,
    MetadataFilter,
    MetadataFilters,
)
from llama_index.core.vector_stores.utils import build_metadata_filter_fn

# A node that does NOT have a "category" key
metadata = {"n1": {"other": 1}}

ne = MetadataFilters(
    filters=[MetadataFilter(key="category", operator=FilterOperator.NE, value="news")]
)
not_eq = MetadataFilters(
    filters=[MetadataFilter(key="category", operator=FilterOperator.EQ, value="news")],
    condition=FilterCondition.NOT,
)

print("category != 'news'      :", build_metadata_filter_fn(metadata.__getitem__, ne)("n1"))
print("NOT(category == 'news') :", build_metadata_filter_fn(metadata.__getitem__, not_eq)("n1"))

---

category != 'news'      : False   # node is incorrectly excluded
NOT(category == 'news') : True    # node is correctly included
RAW_BUFFERClick to expand / collapse

Bug Description

build_metadata_filter_fn in llama-index-core (llama_index/core/vector_stores/utils.py) returns False for every operator when the metadata value for a key is missing (None):

if metadata_value is None:
    return False

For the negation operators NE (!=) and NIN (nin), this is wrong. A node that does not have the filtered key is, trivially, not equal to / not contained in the requested value, so it should match. The current behaviour also makes key != value inconsistent with the logically-equivalent NOT(key == value): for a node missing the key they return opposite results.

This affects the in-memory SimpleVectorStore and any store that relies on build_metadata_filter_fn for metadata filtering.

Version

0.14.22 (current main)

Steps to Reproduce

from llama_index.core.vector_stores.types import (
    FilterCondition,
    FilterOperator,
    MetadataFilter,
    MetadataFilters,
)
from llama_index.core.vector_stores.utils import build_metadata_filter_fn

# A node that does NOT have a "category" key
metadata = {"n1": {"other": 1}}

ne = MetadataFilters(
    filters=[MetadataFilter(key="category", operator=FilterOperator.NE, value="news")]
)
not_eq = MetadataFilters(
    filters=[MetadataFilter(key="category", operator=FilterOperator.EQ, value="news")],
    condition=FilterCondition.NOT,
)

print("category != 'news'      :", build_metadata_filter_fn(metadata.__getitem__, ne)("n1"))
print("NOT(category == 'news') :", build_metadata_filter_fn(metadata.__getitem__, not_eq)("n1"))

Relevant Logs/Tracebacks

category != 'news'      : False   # node is incorrectly excluded
NOT(category == 'news') : True    # node is correctly included

The two expressions are logically equivalent but produce opposite results.

Expected Behavior

NE and NIN should match a node whose metadata is missing the filtered key, mirroring NOT(EQ) / NOT(IN). Positive operators (EQ, IN, GT, CONTAINS, ...) should keep returning False for a missing value.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING