deepset-ai/haystack · error · FilterError
'operator' key missing in {condition}
Error message
'operator' key missing in {condition} What it means
Logical filter conditions (AND/OR groups) must contain an 'operator' key. _logic_condition raises FilterError when the condition dict lacks it, indicating a malformed filter expression.
Source
Thrown at haystack/utils/filters.py:272
COMPARISON_OPERATORS = {
"==": _equal,
"!=": _not_equal,
">": _greater_than,
">=": _greater_than_equal,
"<": _less_than,
"<=": _less_than_equal,
"in": _in,
"not in": _not_in,
}
def _logic_condition(
condition: dict[str, Any], document: Document | ByteStream, strict_datetime_comparison: bool
) -> bool:
if "operator" not in condition:
msg = f"'operator' key missing in {condition}"
raise FilterError(msg)
if "conditions" not in condition:
msg = f"'conditions' key missing in {condition}"
raise FilterError(msg)
operator: str = condition["operator"]
if operator not in LOGICAL_OPERATORS:
msg = f"Unknown logical operator '{operator}'. Valid operators are: {sorted(LOGICAL_OPERATORS)}"
raise FilterError(msg)
conditions: list[dict[str, Any]] = condition["conditions"]
return LOGICAL_OPERATORS[operator](
document=document, conditions=conditions, strict_datetime_comparison=strict_datetime_comparison
)
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.View on GitHub (pinned to e318778c9b)
Solutions
- Add "operator": "AND" (or "OR") at the top of the logical condition.
- Validate filter structure against the documented schema before use.
- Check for code paths that strip or rename keys when building filters dynamically.
Example fix
// before
filters = {"conditions": [{"field": "meta.x", "operator": "==", "value": 1}]}
// after
filters = {"operator": "AND", "conditions": [{"field": "meta.x", "operator": "==", "value": 1}]} Defensive patterns
Strategy: validation
Validate before calling
assert "operator" in condition, f"logical condition needs 'operator': {condition}" Type guard
def is_logical_condition(c: dict) -> bool:
return isinstance(c, dict) and "operator" in c and "conditions" in c Try / catch
try:
ok = document_matches_filter(doc, filters)
except FilterError as e:
raise ValueError(f"malformed filter: {e}") from e Prevention
- Include both 'operator' and 'conditions' in every logical group.
- Validate filters against the documented schema before use.
- Avoid manual dict surgery on filter structures.
When it happens
Trigger: Passing {"conditions": [...]} without the top-level 'operator' key to document_matches_filter or a store's filter application.
Common situations: Hand-written filter dicts in configs; merging/transforming filters programmatically and dropping keys; using the legacy single-dict filter syntax in a context expecting the new nested syntax.
Related errors
- 'conditions' key missing in {condition}
- 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
- Unknown logical operator '{operator}'. Valid operators are:
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/65f0ede49054b3bd.
Report an issue: GitHub.