{"record":{"id":"d8051aaf39e04215","repo":"theonedev/onedev","slug":"count-should-not-be-greater-than-max-page-size-d8051a","errorCode":null,"errorMessage":"Count should not be greater than ${MAX_PAGE_SIZE}","messagePattern":"Count should not be greater than (.+?)","errorType":"http","errorClass":"NotAcceptableException","httpStatus":406,"severity":"warning","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java","lineNumber":211,"sourceCode":"\t@Path(\"/{projectId}/labels\")\n\t@GET\n\tpublic Collection<ProjectLabel> getLabels(@PathParam(\"projectId\") Long projectId) {\n\t\tProject project = projectService.load(projectId);\n\t\tif (!SecurityUtils.canAccessProject(project))\n\t\t\tthrow new UnauthorizedException();\n\t\treturn project.getLabels();\n\t}\n\t\n\t@Api(order=700)\n\t@GET\n    public List<ProjectData> queryProjects(\n    \t\t@QueryParam(\"query\") @Api(description=\"Syntax of this query is the same as in <a href='/~projects'>projects page</a>\", example=\"\\\"Name\\\" is \\\"projectName\\\"\") String query, \n    \t\t@QueryParam(\"offset\") @Api(example=\"0\") int offset, \n    \t\t@QueryParam(\"count\") @Api(example=\"100\") int count) {\n\n\t\tvar subject = SecurityUtils.getSubject();\n\t\tif (!SecurityUtils.isAdministrator(subject) && count > RestConstants.MAX_PAGE_SIZE)\n    \t\tthrow new NotAcceptableException(\"Count should not be greater than \" + RestConstants.MAX_PAGE_SIZE);\n\n\t\tvar parsedQuery = ProjectQuery.parse(query);\n    \t\n    \treturn projectService.query(subject, parsedQuery, false, offset, count).stream()\n    \t\t\t.map(ProjectData::from)\n    \t\t\t.collect(Collectors.toList());\n    }\n\t\n\t@Api(order=750)\n\t@Path(\"/{projectId}/iterations\")\n    @GET\n    public List<Iteration> queryIterations(@PathParam(\"projectId\") Long projectId, @QueryParam(\"name\") String name,\n\t\t\t\t\t\t\t\t\t\t   @QueryParam(\"startBefore\") @Api(exampleProvider=\"getDateExample\", description=\"ISO 8601 date\") String startBefore,\n\t\t\t\t\t\t\t\t\t\t   @QueryParam(\"startAfter\") @Api(exampleProvider=\"getDateExample\", description=\"ISO 8601 date\") String startAfter,\n\t\t\t\t\t\t\t\t\t\t   @QueryParam(\"dueBefore\") @Api(exampleProvider=\"getDateExample\", description=\"ISO 8601 date\") String dueBefore,\n\t\t\t\t\t\t\t\t\t\t   @QueryParam(\"dueAfter\") @Api(exampleProvider=\"getDateExample\", description=\"ISO 8601 date\") String dueAfter,\n\t\t\t\t\t\t\t\t\t\t   @QueryParam(\"closed\") Boolean closed, @QueryParam(\"offset\") @Api(example=\"0\") int offset,\n\t\t\t\t\t\t\t\t\t\t   @QueryParam(\"count\") @Api(example=\"100\") int count) {","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java#L193-L229","documentation":"Thrown by GET /projects (queryProjects) when a non-administrator requests more than RestConstants.MAX_PAGE_SIZE results in one page. The NotAcceptableException maps to HTTP 406 and protects the server from large unbounded queries; admins are exempt from the cap.","triggerScenarios":"Calling GET /~api/projects?count=1000 (or any count > MAX_PAGE_SIZE, typically 100?) with a non-admin token, or omitting count defaults is fine but explicitly passing a large count triggers it.","commonSituations":"Bulk-sync scripts exporting all projects in one call; copying a query from an admin's session to a normal user's token; assuming no pagination limit exists.","solutions":["Reduce the count parameter to RestConstants.MAX_PAGE_SIZE or less and iterate with offset until fewer results than count are returned.","Use an administrator token only if a single oversized page is truly required.","Combine offset pagination with a query filter (e.g. by name) to shrink result sets per page.","Check the API docs / RestConstants for the exact current page size limit on your OneDev version."],"exampleFix":"// before\nGET /~api/projects?offset=0&count=1000 // 406\n// after: paginate\nGET /~api/projects?offset=0&count=100\nGET /~api/projects?offset=100&count=100 // ... until short page","handlingStrategy":"validation","validationCode":"const MAX_PAGE_SIZE = 100; // keep in sync with RestConstants.MAX_PAGE_SIZE\nasync function queryAllProjects(query = '') {\n  const out = [];\n  for (let offset = 0; ; offset += MAX_PAGE_SIZE) {\n    const page = await api.get(`/~api/projects?query=${encodeURIComponent(query)}&offset=${offset}&count=${MAX_PAGE_SIZE}`);\n    out.push(...page);\n    if (page.length < MAX_PAGE_SIZE) return out;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const projects = await api.get(`/~api/projects?count=${count}`);\n} catch (e) {\n  if (e.status === 406) {\n    // count exceeded MAX_PAGE_SIZE — clamp and paginate instead\n  } else throw e;\n}","preventionTips":["Always clamp count to the documented MAX_PAGE_SIZE before calling.","Implement offset-based pagination loops in export scripts by default.","Do not copy oversized queries from admin sessions to normal-user tokens.","Filter with the query parameter to reduce per-page result sizes."],"tags":["rest","pagination","http-406","query"],"backgroundTag":"invalid-query-parameter","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}