makeplane/plane · error · ValueError

Filter validation errors: {'; '.join(validation_errors)}

Error message

Filter validation errors: {'; '.join(validation_errors)}

What it means

ValueError raised at the end of `convert` (converters.py:396) when `strict=True` and one or more per-field validation errors were collected during the loop (unsupported keys, invalid UUIDs, bad choices, invalid dates, etc.). All individual errors are joined with '; ' into a single message. It is the aggregate strict-mode failure for the whole legacy filter payload.

Source

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

                self._add_rich_filter(rich_filters, rich_field_name, "in", valid_values)

            else:
                # Handle single values
                # Process date fields with helper method
                if self._process_date_field(rich_field_name, [value], strict, validation_errors, rich_filters):
                    continue

                # For non-list values, use __exact operator for non-date fields
                if self._validate_value(rich_field_name, value):
                    self._add_rich_filter(rich_filters, rich_field_name, "exact", value)
                else:
                    error_msg = f"Invalid value for {legacy_key}: {value}"
                    self._add_validation_error(strict, validation_errors, error_msg)

        # Raise validation errors if in strict mode
        if strict and validation_errors:
            error_message = f"Filter validation errors: {'; '.join(validation_errors)}"
            raise ValueError(error_message)

        # Convert flat dict to rich filter format
        return self._format_as_rich_filter(rich_filters)

    def _format_as_rich_filter(self, flat_filters: Dict[str, Any]) -> Dict[str, Any]:
        """
        Convert a flat dictionary of filters to the proper rich filter format.

        Args:
            flat_filters: Dictionary with field__lookup keys and values

        Returns:
            Rich filter format using logical operators (and/or/not)
        """
        if not flat_filters:
            return {}

        # If only one filter, return as leaf node

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Read the joined message - each segment names the offending key and value; fix each one.
  2. Cross-check keys against converter.FIELD_MAPPINGS and values against VALID_CHOICES / UUID_FIELDS / DATE_FIELDS.
  3. Run with strict=False first to see which values are silently dropped, then correct them before enabling strict.
  4. Validate the payload client-side against the same field/choice maps before sending.

Example fix

# before
legacy = {"state": ["bad-uuid"], "priority": ["extreme"], "target_date": ["foo"]}
converter.convert(legacy, strict=True)  # raises aggregated errors

# after - fix each value
legacy = {
  "state": ["<valid-state-uuid>"],
  "priority": ["urgent"],
  "target_date": ["2024-08-12"],
}
converter.convert(legacy, strict=True)
Defensive patterns

Strategy: validation

Validate before calling

# Replay the converter's own strict checks before the real call
def preview_errors(converter, legacy_filters):
    errors = []
    try:
        converter.convert(legacy_filters, strict=True)
    except ValueError as e:
        # message: 'Filter validation errors: <seg>; <seg>; ...'
        body = str(e).split('Filter validation errors:', 1)[-1]
        errors = [s.strip() for s in body.split(';') if s.strip()]
    return errors

Try / catch

try:
    rich = converter.convert(legacy, strict=True)
except ValueError as e:
    # surface the per-field segments to the client for fixing
    return bad_request({'errors': str(e).split('Filter validation errors:')[-1].split('; ')})

Prevention

When it happens

Trigger: Calling `converter.convert(legacy_filters, strict=True)` where any field fails its specific check: unsupported key (not in FIELD_MAPPINGS), invalid UUID, invalid choice value, no valid values in a list, invalid date, or an invalid single value. Each failure is appended to validation_errors; if non-empty at the end, this raises.

Common situations: Bulk-migrating legacy filter JSON with strict=True to surface all problems at once; client sending a filter payload with mixed valid/invalid keys; integrating an external tool whose filter vocabulary does not match FIELD_MAPPINGS; debug runs that enable strict to find data-quality issues.

Related errors


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