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

  1. Add the 'value' key to the condition dict: {'field': ..., 'operator': ..., 'value': ...}
  2. Check that any code building filter dicts programmatically always includes 'value', even for empty-string or None values
  3. 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

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


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/119d3bc00cd874b0. Report an issue: GitHub.