SonarSource/sonarqube · error · IllegalArgumentException
Page size must be >= 0
Error message
Page size must be >= 0
What it means
SearchTemplatesAction.validatePaginationParameters rejects a negative ps (page size) parameter for api/permissions/search_templates. Page size is optional, but when supplied it must be a non-negative integer not exceeding RESULTS_MAX_SIZE.
Solutions
- Pass a non-negative ps value (e.g. ps=100) or omit ps entirely to use the default
- Fix the pagination loop so page size is computed as Math.max(0, remaining)
- Validate user-supplied page size in your UI before forwarding it to the API
Example fix
// before
const ps = limit - fetched; // can go negative
await searchTemplates({ ps });
// after
const ps = Math.max(0, Math.min(limit - fetched, 500));
await searchTemplates({ ps }); Defensive patterns
Strategy: validation
Validate before calling
if (ps != null && ps < 0) throw new Error('Page size must be >= 0');
await searchTemplates({ ps }); Type guard
function isValidPageSize(ps) { return ps == null || (Number.isInteger(ps) && ps >= 0); } Try / catch
try { await searchTemplates({ ps }); } catch (e) { if (e.message.includes('Page size must be >= 0')) { return searchTemplates({}); } throw e; } Prevention
- Clamp computed page sizes with Math.max(0, n)
- Omit ps when you want the server default
- Sanitize user input that feeds pagination params
When it happens
Trigger: GET api/permissions/search_templates with ps=-1 or any negative page-size value; SDKs or scripts computing page size dynamically (e.g. total-fetched differences) yielding negative numbers.
Common situations: Pagination loops that compute remaining items incorrectly and pass negative page sizes; hand-written queries with placeholder values not replaced (ps=-1); copying examples that used invalid values.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Page size must not exceed
- Backup XML is not valid. Root element must be
- Entity not found
- Entity not found
- Failed to set the New Code Definition. The given value is…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/d1b8d68ac2828966.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java:123
public void handle(Request wsRequest, Response wsResponse) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
SearchTemplatesRequest request = new SearchTemplatesRequest()
.setQuery(wsRequest.param(Param.TEXT_QUERY))
.setPage(wsRequest.paramAsInt(Param.PAGE))
.setPageSize(wsRequest.paramAsInt(Param.PAGE_SIZE));
validatePaginationParameters(request);
checkGlobalAdmin(userSession);
SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(load(dbSession, request));
writeProtobuf(searchTemplatesWsResponse, wsRequest, wsResponse);
}
}
private static void validatePaginationParameters(SearchTemplatesRequest request) {
if (request.getPageSize() != null) {
if (request.getPageSize() < 0) {
throw new IllegalArgumentException("Page size must be >= 0");
}
if (request.getPageSize() > RESULTS_MAX_SIZE) {
throw new IllegalArgumentException("Page size must not exceed " + RESULTS_MAX_SIZE);
}
}
}
private static void buildDefaultTemplatesResponse(SearchTemplatesWsResponse.Builder response, SearchTemplatesData data) {
TemplateIdQualifier.Builder templateUuidQualifierBuilder = TemplateIdQualifier.newBuilder();
ResolvedDefaultTemplates resolvedDefaultTemplates = data.defaultTemplates();
response.addDefaultTemplates(templateUuidQualifierBuilder
.setQualifier(ComponentQualifiers.PROJECT)
.setTemplateId(resolvedDefaultTemplates.getProject()));
resolvedDefaultTemplates.getApplication()
.ifPresent(viewDefaultTemplate -> response.addDefaultTemplates(
templateUuidQualifierBuilderView on GitHub (pinned to 184c821202)