deepset-ai/haystack · error · FilterError
'value' key missing in {condition}
Error message
'value' key missing in {condition} What it means
FilterError raised by `_comparison_condition` in haystack/utils/filters.py when a comparison condition dict lacks the required 'value' key. Haystack filters use the structured form {'field': ..., 'operator': ..., 'value': ...}, and the value is what the document attribute is compared against; without it the comparison is undefined.
Source
Thrown at haystack/utils/filters.py:302
def _comparison_condition(
condition: dict[str, Any], document: Document | ByteStream, strict_datetime_comparison: bool
) -> bool:
if "field" not in condition:
# 'field' key is only found in comparison dictionaries.
# We assume this is a logic dictionary since it's not present.
return _logic_condition(
condition=condition, document=document, strict_datetime_comparison=strict_datetime_comparison
)
field: str = condition["field"]
if "operator" not in condition:
msg = f"'operator' key missing in {condition}"
raise FilterError(msg)
if "value" not in condition:
msg = f"'value' key missing in {condition}"
raise FilterError(msg)
if "." in field:
# Handles fields formatted like so:
# 'meta.person.name'
parts = field.split(".")
document_value = getattr(document, parts[0])
for part in parts[1:]:
if not isinstance(document_value, dict) or part not in document_value:
# If a field is not found (or an intermediate value is not a dict,
# e.g. None) we treat it as None
document_value = None
break
document_value = document_value[part]
elif field not in [f.name for f in fields(document)]:
# Converted legacy filters don't add the `meta.` prefix, so we assume
# that all filter fields that are not actual fields in Document are converted
# filters.
#View on GitHub (pinned to e318778c9b)
Solutions
- Add the 'value' key to the condition dict: {'field': ..., 'operator': ..., 'value': ...}
- Check that any code building filter dicts programmatically always includes 'value', even for empty-string or None values
- Validate the filter dict structure before passing it to the component
Example fix
// before
filters = {"field": "meta.year", "operator": "=="}
// after
filters = {"field": "meta.year", "operator": "==", "value": 2024} Defensive patterns
Strategy: validation
Validate before calling
REQUIRED = {"field", "operator", "value"}
def validate_filter(cond):
missing = REQUIRED - cond.keys()
if missing:
raise ValueError(f"filter condition missing keys: {missing}") Type guard
def is_valid_condition(c) -> bool:
return isinstance(c, dict) and {"field", "operator", "value"}.issubset(c.keys()) Try / catch
from haystack.utils import FilterError
try:
doc_matches = document_matches_filter(document, condition)
except FilterError as e:
log.error("Invalid filter condition: %s", e)
doc_matches = False Prevention
- Always build filters with all three keys: field, operator, value
- Centralize filter construction in one factory function that validates keys
- Never conditionally omit the value key; include None explicitly if needed
When it happens
Trigger: Calling document_matches_filter/_and/_or (directly or via run(... filters=...) on DocumentFilter-like components) with a condition dict that has 'field' and 'operator' but no 'value', e.g. {'field': 'meta.year', 'operator': '=='} instead of {'field': 'meta.year', 'operator': '==', 'value': 2024}.
Common situations: Hand-written filter dicts with a missing key; programmatically built filters where a variable holding the value is None and the key was conditionally omitted; older 1.x-style filter dicts migrated to 2.x without all keys.
Related errors
- Unknown comparison operator '{operator}'. Valid operators ar
- Filter value can't be of type {type(filter_value)} using ope
- Can't compare strings using operators '>', '>=', '<', '<='.
- Filter value must be a `list` when using operator 'in' or 'n
- 'operator' key missing in {condition}
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/119d3bc00cd874b0.
Report an issue: GitHub.