deepset-ai/haystack · error · FilterError

Can't compare strings using operators '>', '>=', '<', '<='.

Error message

Can't compare strings using operators '>', '>=', '<', '<='. Strings are only comparable if they are ISO formatted dates.

What it means

When comparing with ordering operators, plain strings are only interpretable if they are ISO-formatted dates; dateutil.parser.parse is used to convert them. If parsing fails, FilterError is raised because Haystack refuses to do arbitrary lexicographic string comparisons.

Source

Thrown at haystack/utils/filters.py:182

    )
    if not comparable:
        return False
    return value > filter_value


def _parse_date(value: str) -> datetime:
    """Try parsing the value as an ISO format date, then fall back to dateutil.parser."""
    try:
        return datetime.fromisoformat(value)
    except (ValueError, TypeError):
        try:
            return dateutil.parser.parse(value)
        except (ValueError, TypeError) as exc:
            msg = (
                "Can't compare strings using operators '>', '>=', '<', '<='. "
                "Strings are only comparable if they are ISO formatted dates."
            )
            raise FilterError(msg) from exc


def _ensure_both_dates_naive_or_aware(date1: datetime, date2: datetime) -> tuple[datetime, datetime]:
    """Ensure that both dates are either naive or aware."""
    # Both naive
    if date1.tzinfo is None and date2.tzinfo is None:
        return date1, date2

    # Both aware
    if date1.tzinfo is not None and date2.tzinfo is not None:
        return date1, date2

    # One naive, one aware
    if date1.tzinfo is None:
        date1 = date1.replace(tzinfo=date2.tzinfo)
    else:
        date2 = date2.replace(tzinfo=date1.tzinfo)
    return date1, date2

View on GitHub (pinned to e318778c9b)

Solutions

  1. Use ISO 8601 strings, e.g. '2024-03-01' or '2024-03-01T00:00:00'.
  2. Compare datetime.datetime objects instead of strings.
  3. For non-date strings, don't use ordering operators — use '=='/'in' or store a sortable key.

Example fix

// before
filters = {"operator": ">", "field": "meta.date", "value": "March 3rd 2024"}
// after
filters = {"operator": ">", "field": "meta.date", "value": "2024-03-03"}
Defensive patterns

Strategy: validation

Validate before calling

from dateutil import parser
try:
    parser.isoparse(value)
except (ValueError, TypeError):
    raise ValueError("use ISO 8601 dates for string comparisons")

Type guard

def is_iso_date(s: str) -> bool:
    try:
        dateutil.parser.isoparse(s)
        return True
    except (ValueError, TypeError):
        return False

Try / catch

try:
    ok = document_matches_filter(doc, filters)
except FilterError:
    ok = False

Prevention

When it happens

Trigger: Filters like {"operator": ">", "field": "meta.created", "value": "March 2024"} or non-date strings such as 'abc' compared with >, >=, <, <=.

Common situations: Storing human-readable dates in metadata instead of ISO 8601; comparing free-text fields with ordering operators; timezone-aware vs naive ISO strings.

Related errors


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