langgenius/dify · warning · ValueError

sort_order must be asc or desc

Error message

sort_order must be asc or desc

What it means

A Pydantic field_validator on RosterListQuery.sort_order: the value (trimmed, lowercased) must be one of {asc, desc}. Any other value is rejected with a 422. The validator normalizes case first, so 'DESC' or ' Asc ' are accepted but 'ascending' or '1' are not.

Source

Thrown at api/controllers/console/agent/roster.py:220

            return []
        if isinstance(value, list):
            return [str(item).strip() for item in value if str(item).strip()]
        raise ValueError("Unsupported query list type.")

    @field_validator("sort_by")
    @classmethod
    def validate_sort_by(cls, value: str) -> str:
        normalized = value.strip().lower()
        if normalized not in {"created_at", "updated_at"}:
            raise ValueError("sort_by must be created_at or updated_at")
        return normalized

    @field_validator("sort_order")
    @classmethod
    def validate_sort_order(cls, value: str) -> str:
        normalized = value.strip().lower()
        if normalized not in {"asc", "desc"}:
            raise ValueError("sort_order must be asc or desc")
        return normalized


class AgentStatisticsQuery(BaseModel):
    source: str | None = Field(
        default=None,
        description=(
            "Filter by a structured webapp:<app_id> or workflow:<app_id> source ID. "
            "Legacy invoke sources and exact workflow version/node source IDs remain supported."
        ),
    )
    start: str | None = Field(default=None, description="Start date (YYYY-MM-DD HH:MM)")
    end: str | None = Field(default=None, description="End date (YYYY-MM-DD HH:MM)")

    @field_validator("source", "start", "end", mode="before")
    @classmethod
    def empty_string_to_none(cls, value: str | None) -> str | None:
        if value == "":

View on GitHub (pinned to ef8544b173)

Solutions

  1. Send ?sort_order=asc or ?sort_order=desc (case-insensitive, trimmed).
  2. Map the UI's direction token to asc/desc before submitting.
  3. Omit sort_order to use the default (desc).
  4. Update the client's sort-order vocabulary from the schema.

Example fix

// before
query.sort_order = 'ascending'
// after
query.sort_order = 'asc'
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED_SORT_ORDER = {'asc', 'desc'}

def normalize_sort_order(value: str) -> str:
    norm = (value or '').strip().lower()
    return norm if norm in ALLOWED_SORT_ORDER else 'desc'

Type guard

def is_valid_sort_order(value: str) -> bool:
    return isinstance(value, str) and value.strip().lower() in {'asc', 'desc'}

Prevention

When it happens

Trigger: GET /console/agents with ?sort_order=<anything else>, e.g. ?sort_order=ascending, ?sort_order=1, ?sort_order=-1. Common when a UI toggles pass numeric or long-form direction tokens.

Common situations: Frontend that emits 'ascending'/'descending' or 1/-1 from a sort toggle; a generic grid component that passes its own direction vocabulary; typo.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/c43eb5b7dfb3da3e. Report an issue: GitHub.