{"record":{"id":"fd2e19eae5286c51","repo":"Comfy-Org/ComfyUI","slug":"invalid-cursor","errorCode":"INVALID_CURSOR","errorMessage":"cursor pagination is not supported for sort={sort!r}","messagePattern":"cursor pagination is not supported for sort=(.+?)","errorType":"http","errorClass":"InvalidCursorError","httpStatus":400,"severity":"error","filePath":"app/assets/services/asset_management.py","lineNumber":301,"sourceCode":"    any_tags: Sequence[str] | None = None,\n) -> ListAssetsResult:\n    \"\"\"List assets with optional cursor pagination.\n\n    When ``after`` is supplied it overrides ``offset``. The cursor's sort field\n    must match ``sort`` and be in the cursor-supported allowlist; mismatches\n    raise InvalidCursorError so the handler can map to 400 INVALID_CURSOR.\n    \"\"\"\n    cursor_value: object | None = None\n    cursor_id: str | None = None\n    # Mint next_cursor on every page where the sort is cursor-supported, not\n    # only when the request itself arrived with a cursor. Otherwise a first\n    # request (no `after`) returns next_cursor=None and the client can never\n    # enter cursor mode.\n    mint_cursor = sort in _CURSOR_SORT_FIELDS\n\n    if after is not None:\n        if sort not in _CURSOR_SORT_FIELDS:\n            raise InvalidCursorError(\n                f\"cursor pagination is not supported for sort={sort!r}\"\n            )\n        payload = decode_cursor(after, _CURSOR_SORT_FIELDS, expected_order=order)\n        if payload.sort_field != sort:\n            raise InvalidCursorError(\n                f\"cursor sort field {payload.sort_field!r} does not match request sort {sort!r}\"\n            )\n        cursor_value, cursor_id = _resolve_cursor_value(payload), payload.id\n\n    # Over-fetch by one row so we can distinguish \"exactly `limit` rows total\n    # remaining\" from \"more rows past this page\" without a second query. Drop\n    # the sentinel before returning.\n    fetch_limit = limit + 1 if mint_cursor else limit\n\n    with create_session() as session:\n        refs, tag_map, total = list_references_page(\n            session,\n            owner_id=owner_id,","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/app/assets/services/asset_management.py#L283-L319","documentation":"InvalidCursorError raised by the listing service when a request supplies an `after` cursor while `sort` is not one of the cursor-supported fields (created_at, updated_at, name, size). The service only enters cursor mode for those sorts; other sort orders use offset pagination and cannot interpret a cursor.","triggerScenarios":"Calling the list endpoint with both after=<cursor> and a sort value outside ('created_at','updated_at','name','size'), e.g. sort=random or a custom sort, with a next_cursor carried over from a previous page.","commonSituations":"Client changes the sort control mid-pagination but keeps the after parameter; a new sort option added server-side without extending _CURSOR_SORT_FIELDS; saved/bookmarked URLs that embed an old cursor being replayed with a different sort.","solutions":["Drop the after parameter when requesting a non-cursor-supported sort.","Keep the sort stable across pages: reuse the exact sort that minted the cursor.","If a new sort must support cursors, add the field to _CURSOR_SORT_FIELDS and implement its keyset comparison.","Catch InvalidCursorError and return 400 INVALID_CURSOR so the client can reset to page one."],"exampleFix":"# before\nlist_assets(sort=\"random\", after=next_cursor)\n\n# after\nCURSOR_SORTS = {\"created_at\", \"updated_at\", \"name\", \"size\"}\nlist_assets(sort=\"random\", after=next_cursor if sort in CURSOR_SORTS else None)","handlingStrategy":"validation","validationCode":"CURSOR_SORTS = {\"created_at\", \"updated_at\", \"name\", \"size\"}\n\ndef safe_after(sort: str, after: str | None) -> str | None:\n    return after if (after and sort in CURSOR_SORTS) else None","typeGuard":null,"tryCatchPattern":"try:\n    page = list_assets(sort=sort, after=after)\nexcept InvalidCursorError as e:\n    # 400: reset pagination\n    page = list_assets(sort=sort, after=None)","preventionTips":["Clear the after token whenever the sort control changes.","Only send cursors for the four supported sorts; use offset pagination otherwise.","On 400 INVALID_CURSOR, restart from page one."],"tags":["pagination","cursor","api","bad-request"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}