makeplane/plane · error · ValueError

Invalid date format: {date_part}

Error message

Invalid date format: {date_part}

What it means

ValueError raised in `_process_date_field` (converters.py:296) when `strict=True`, the directional value splits into >= 2 parts, but `parts[0]` (the date_part) fails `_validate_date` (dateutil parse). Only the date portion is reported. Direction values other than 'after'/'before' are silently skipped (no error), so this error is specifically about the date half.

Source

Thrown at apps/api/plane/utils/filters/converters.py:296

                if not self._validate_date(value):
                    if strict:
                        raise ValueError(f"Invalid date format: {value}")
                    continue
                exact_dates.append(value)
            else:
                # Directional date - only handle basic after/before
                parts = value.split(";")
                if len(parts) < 2:
                    if strict:
                        raise ValueError(f"Invalid date format: {value}")
                    continue

                date_part = parts[0]
                direction = parts[1]

                if not self._validate_date(date_part):
                    if strict:
                        raise ValueError(f"Invalid date format: {date_part}")
                    continue

                if direction == "after":
                    after_dates.append(date_part)
                elif direction == "before":
                    before_dates.append(date_part)
                # Skip unsupported directions

        # Determine return format
        result = {}
        if len(after_dates) == 1 and len(before_dates) == 1 and len(exact_dates) == 0:
            # Simple range: one after and one before
            start_date = min(after_dates[0], before_dates[0])
            end_date = max(after_dates[0], before_dates[0])
            self._add_rich_filter(result, field_name, "range", [start_date, end_date])
        elif len(exact_dates) == 1 and len(after_dates) == 0 and len(before_dates) == 0:
            # Single exact date
            self._add_rich_filter(result, field_name, "exact", exact_dates[0])

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Put a valid ISO date in the date slot and 'after'/'before' in the direction slot: `<ISO-date>;after`.
  2. Verify ordering - date comes first, then direction.
  3. Use strict=False to skip values with unparseable date parts.
  4. Pre-validate parts[0] with dateutil.parser.parse client-side before composing the directional string.

Example fix

# before
filters = {"target_date": ["after;2024-08-12"]}  # 'after' parsed as date -> fails

# after
filters = {"target_date": ["2024-08-12;after"]}
Defensive patterns

Strategy: validation

Validate before calling

from dateutil.parser import parse as dateutil_parse

def is_valid_directional_date(value: str) -> bool:
    # date_part (parts[0]) must parse; direction must be after|before (else silently skipped)
    if ';' not in value:
        return True
    parts = value.split(';')
    if len(parts) < 2:
        return False
    try:
        dateutil_parse(parts[0]); return True
    except (ValueError, TypeError):
        return False

Try / catch

try:
    converter.convert(filters, strict=True)
except ValueError as e:
    if 'Invalid date format' in str(e):
        # e message contains only the bad date_part
        report(e)

Prevention

When it happens

Trigger: Passing strict=True with a directional value whose date part is unparseable - e.g. 'NaN;after', '2024-13-99;before', or 'foo;after'. The message interpolates only the date_part, not the direction.

Common situations: User fills a date range with a label instead of a date in the first slot; locale-formatted date dateutil rejects; copy-paste placing the direction first ('after;2024-08-12') - the parser then tries 'after' as a date and fails.

Related errors


AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12). Data as JSON: /api/errors/62d6f3599fcdd084. Report an issue: GitHub.