{"record":{"id":"9e47555402984df2","repo":"infiniflow/ragflow","slug":"field-name-must-contain-at-most-rest-api-max-id","errorCode":null,"errorMessage":"{field_name} must contain at most {REST_API_MAX_IDS} IDs","messagePattern":"(.+?) must contain at most (.+?) IDs","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"api/utils/pagination_utils.py","lineNumber":50,"sourceCode":"\n\ndef validate_rest_api_page_size(page_size) -> int:\n    \"\"\"Validate page_size, if invalid, silent fallback to default page_size, and validate it against the public maximum.\"\"\"\n    try:\n        int_page_size = int(page_size)\n    except (TypeError, ValueError):\n        return DEFAULT_PAGE_SIZE\n    if int_page_size < 1:\n        return DEFAULT_PAGE_SIZE\n    if int_page_size > REST_API_MAX_PAGE_SIZE:\n        raise ValueError(f\"page_size must be less than or equal to {REST_API_MAX_PAGE_SIZE}\")\n    return int_page_size\n\n\ndef validate_rest_api_ids(ids: list | None, field_name: str = \"ids\") -> list | None:\n    \"\"\"Validate REST API ID lists against the public maximum.\"\"\"\n    if ids is not None and len(ids) > REST_API_MAX_IDS:\n        raise ValueError(f\"{field_name} must contain at most {REST_API_MAX_IDS} IDs\")\n    return ids\n","sourceCodeStart":32,"sourceCodeEnd":52,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/utils/pagination_utils.py#L32-L52","documentation":"Thrown by validate_rest_api_ids in api/utils/pagination_utils.py when a request supplies a list of IDs (e.g. dataset_id, document_id lists) longer than the public REST API cap REST_API_MAX_IDS. The cap protects batch endpoints from oversized payloads. It is a plain ValueError raised before any database or tenant lookup happens.","triggerScenarios":"Calling a bulk REST endpoint (delete/update datasets or documents by IDs) with a 'ids' (or similarly named) array whose length exceeds REST_API_MAX_IDS, e.g. POST/PUT with hundreds of UUIDs in one request while the constant is 100 (or whatever the configured max is).","commonSituations":"Scripts that migrate or sync thousands of documents and pass the whole ID list in one call; frontend 'select all' actions that collect every row's ID; pagination bugs where an unbounded query result is fed directly into a batch delete.","solutions":["Chunk the ID list client-side into batches of at most REST_API_MAX_IDS (check its value in api/utils/pagination_utils.py or the config constants) and issue one request per batch.","If you genuinely need larger batches, ask the maintainer to raise REST_API_MAX_IDS or use an async task/job endpoint instead of the synchronous batch API.","Add a unit assertion in your client code that fails fast when an outbound ID list exceeds the cap."],"exampleFix":"# before\nresp = client.delete(\"/api/v1/datasets\", json={\"ids\": all_ids})  # 5000 ids\n\n# after\nMAX_IDS = 100  # must match REST_API_MAX_IDS\nfor i in range(0, len(all_ids), MAX_IDS):\n    resp = client.delete(\"/api/v1/datasets\", json={\"ids\": all_ids[i:i+MAX_IDS]})\n    resp.raise_for_status()","handlingStrategy":"validation","validationCode":"MAX_IDS = 100  # keep in sync with REST_API_MAX_IDS\n\ndef safe_batches(ids: list[str], size: int = MAX_IDS) -> list[list[str]]:\n    if len(ids) > size:\n        return [ids[i:i+size] for i in range(0, len(ids), size)]\n    return [ids]","typeGuard":"def is_within_id_cap(ids: list[str] | None) -> bool:\n    return ids is None or len(ids) <= REST_API_MAX_IDS","tryCatchPattern":"try:\n    resp = api.delete_datasets(ids)\nexcept ValueError as e:\n    if \"at most\" in str(e) and \"IDs\" in str(e):\n        for batch in chunks(ids, MAX_IDS):\n            api.delete_datasets(batch)\n    else:\n        raise","preventionTips":["Hard-code the REST_API_MAX_IDS value as a client constant and assert on every batch call.","Never feed an unbounded SELECT result into a single batch request.","Prefer job/async endpoints for bulk operations beyond the cap."],"tags":["rest-api","validation","batch-operations","pagination"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}