deepset-ai/haystack · error · FilterError
Filter value must be a `list` when using operator 'in' or 'n
Error message
Filter value must be a `list` when using operator 'in' or 'not in', received type '{type(filter_value)}' What it means
The 'in' and 'not in' operators require the filter value to be a list; _in raises FilterError for any other type. Since _not_in delegates to _in, both operators enforce this.
Source
Thrown at haystack/utils/filters.py:247
def _less_than_equal(value: Any, filter_value: Any, strict_datetime_comparison: bool) -> bool:
if value is None or filter_value is None:
# We can't compare None values reliably using operators '>', '>=', '<', '<='
return False
value, filter_value, comparable = _prepare_ordering_comparison(
value=value, filter_value=filter_value, strict_datetime_comparison=strict_datetime_comparison
)
if not comparable:
return False
return value <= filter_value
def _in(value: Any, filter_value: Any, strict_datetime_comparison: bool) -> bool:
if not isinstance(filter_value, list):
msg = (
f"Filter value must be a `list` when using operator 'in' or 'not in', received type '{type(filter_value)}'"
)
raise FilterError(msg)
return any(_equal(e, value, strict_datetime_comparison) for e in filter_value)
def _not_in(value: Any, filter_value: Any, strict_datetime_comparison: bool) -> bool:
return not _in(value=value, filter_value=filter_value, strict_datetime_comparison=strict_datetime_comparison)
COMPARISON_OPERATORS = {
"==": _equal,
"!=": _not_equal,
">": _greater_than,
">=": _greater_than_equal,
"<": _less_than,
"<=": _less_than_equal,
"in": _in,
"not in": _not_in,
}
View on GitHub (pinned to e318778c9b)
Solutions
- Wrap the value in a list, e.g. ["news"].
- Use '==' or '!=' if you actually mean single-value equality.
- Validate that 'in'/'not in' filter values are lists before applying filters.
Example fix
// before
filters = {"operator": "in", "field": "meta.tag", "value": "news"}
// after
filters = {"operator": "in", "field": "meta.tag", "value": ["news"]} Defensive patterns
Strategy: validation
Validate before calling
if f.get("operator") in {"in", "not in"} and not isinstance(f.get("value"), list):
f["value"] = [f["value"]] Type guard
def is_list_value(f: dict) -> bool:
return f.get("operator") not in {"in", "not in"} or isinstance(f.get("value"), list) Try / catch
try:
ok = document_matches_filter(doc, filters)
except FilterError as e:
logger.warning("invalid filter: %s", e)
ok = False Prevention
- Always wrap values in a list for 'in'/'not in'.
- Use '=='/'!=' for single-value checks.
- Normalize filter values in a shared helper before applying.
When it happens
Trigger: Filters like {"operator": "in", "field": "meta.tag", "value": "news"} (a bare string) or a dict/int value.
Common situations: Forgetting to wrap a single value in a list when switching from '==' to 'in'; programmatic filter builders that pass scalars through.
Related errors
- Filter value can't be of type {type(filter_value)} using ope
- Unknown logical operator '{operator}'. Valid operators are:
- 'response_fn' must return an assistant ChatMessage, got '{re
- Cannot stream multiple responses, please set n=1.
- A `ChatMessage` must contain at least one `TextContent`, `To
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/f703f90e3f2ccf39.
Report an issue: GitHub.