run-llama/llama_index · error · TypeError
Both metadata_value and value should be strings to be used w
Error message
Both metadata_value and value should be strings to be used with a TEXT_MATCH_INSENSITIVE filter
What it means
Same guard as TEXT_MATCH but for FilterOperator.TEXT_MATCH_INSENSITIVE: the case-insensitive substring check calls `.lower()` on both sides, so both the filter value and the node's metadata value must be str. A TypeError is raised when either side is a non-string type, instead of an AttributeError from calling .lower() on an int. This is evaluated per candidate node during client-side filtering.
Source
Thrown at llama-index-core/llama_index/core/vector_stores/utils.py:148
if operator == FilterOperator.LTE:
return metadata_value <= value
if operator == FilterOperator.IN:
return metadata_value in value
if operator == FilterOperator.NIN:
return metadata_value not in value
if operator == FilterOperator.CONTAINS:
return value in metadata_value
if operator == FilterOperator.TEXT_MATCH:
if isinstance(value, str) and isinstance(metadata_value, str):
return value in metadata_value
raise TypeError(
"Both metadata_value and value should be strings to be used with a "
"TEXT_MATCH filter"
)
if operator == FilterOperator.TEXT_MATCH_INSENSITIVE:
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 = TrueView on GitHub (pinned to afd0fef371)
Solutions
- Pass a str value: `MetadataFilter(key="name", value="alice", operator=FilterOperator.TEXT_MATCH_INSENSITIVE)`.
- For collections use `FilterOperator.IN` / `ANY` / `CONTAINS` instead of text-match operators.
- Normalize metadata types at ingestion so filtered fields are always str (or always the intended type).
- Skip None values by using `FilterOperator.IS_EMPTY` for missing-field checks.
Example fix
# before f = MetadataFilter(key="tags", value=["ai"], operator=FilterOperator.TEXT_MATCH_INSENSITIVE) # after f = MetadataFilter(key="tags", value="ai", operator=FilterOperator.TEXT_MATCH_INSENSITIVE) # or for collections: f = MetadataFilter(key="tags", value=["ai"], operator=FilterOperator.IN)
Defensive patterns
Strategy: type-guard
Validate before calling
def insensitive_filter_valid(value) -> bool:
return isinstance(value, str) Type guard
def is_insensitive_match_safe(filter_, sample_metadata: dict) -> bool:
from llama_index.core.vector_stores import FilterOperator
if filter_.operator is not FilterOperator.TEXT_MATCH_INSENSITIVE:
return True
stored = sample_metadata.get(filter_.key)
return isinstance(filter_.value, str) and isinstance(stored, str) Try / catch
try:
result = store.query(query)
except TypeError as e:
if "TEXT_MATCH_INSENSITIVE" in str(e):
# switch to IN for collections or coerce value to str, then rebuild query
raise ValueError("use str values or FilterOperator.IN for lists") from e
raise Prevention
- Use IN/ANY/CONTAINS for list values, TEXT_MATCH* only for single strings.
- Normalize optional fields to "" or use IS_EMPTY instead of relying on None.
- Test filters against representative metadata samples before deploying.
When it happens
Trigger: Querying with `operator=FilterOperator.TEXT_MATCH_INSENSITIVE` where the filter value is non-str (int, None, list) or where stored metadata under the filter key is numeric/None in any node being evaluated; e.g. `MetadataFilter(key="tags", value=["ai"], operator=TEXT_MATCH_INSENSITIVE)`.
Common situations: Passing arrays to a single-value operator (should use IN/ANY/CONTAINS); optional metadata fields that are None on some documents; mixed-type metadata after schema drift or multi-source ingestion; forgetting to stringify config-supplied filter values.
Related errors
- Both metadata_value and value should be strings to be used w
- Cannot filter stores that were persisted without metadata. P
- Vector Store only supports exact match filters. Please use E
- Value for metadata {key} must be one of (str, int, float, No
- Invalid operator: {operator}
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/c8fada878c7ae5cf.
Report an issue: GitHub.