{"record":{"id":"d20eab0862003190","repo":"halo-dev/halo","slug":"page-number-must-be-a-number","errorCode":null,"errorMessage":"Page number must be a number","messagePattern":"Page number must be a number","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"api/src/main/java/run/halo/app/theme/router/PageUrlUtils.java","lineNumber":104,"sourceCode":"        return Objects.toString(path, \"/\");\n    }\n\n    private static String appendPagePart(String path, long page) {\n        return PathUtils.combinePath(path, PAGE_PART, String.valueOf(page));\n    }\n\n    private static String toNextPage(String pageStr, long total) {\n        long page = Math.min(parseInt(pageStr) + 1, Math.max(total, 1));\n        return String.valueOf(page);\n    }\n\n    private static int toPrevPage(String pageStr) {\n        return Math.max(parseInt(pageStr) - 1, 1);\n    }\n\n    private static int parseInt(String pageStr) {\n        if (!NumberUtils.isParsable(pageStr)) {\n            throw new IllegalArgumentException(\"Page number must be a number\");\n        }\n        return NumberUtils.toInt(pageStr, 1);\n    }\n}\n","sourceCodeStart":86,"sourceCodeEnd":109,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/api/src/main/java/run/halo/app/theme/router/PageUrlUtils.java#L86-L109","documentation":"PageUrlUtils.parseInt is used by the theme router's toNextPage/toPrevPage helpers to derive adjacent page numbers from the current page string. It throws IllegalArgumentException when NumberUtils.isParsable(pageStr) is false, i.e. the value is not a numeric literal. This is part of building pagination URLs for theme page routes.","triggerScenarios":"A theme page request whose page path/param is non-numeric, e.g. /page/abc/ or ?page=next. A permalink rule or rewrite that injects a non-integer segment into the page position. A crawler hitting an old or malformed page URL.","commonSituations":"Custom permalink patterns that accidentally route non-numeric tokens into the page slot; migration from a CMS whose page URLs used words; bots probing arbitrary path segments under /page/.","solutions":["Correct the page segment in the URL to an integer (e.g. /page/2/).","If you control permalink rules, ensure only \\d+ can land in the page position.","Return a 404 for non-numeric page paths at the routing layer instead of letting parseInt throw.","Audit theme templates that construct next/prev links to always emit numeric page values."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!NumberUtils.isParsable(pageStr)) {\n    // return 404 / default page 1 instead of calling toNextPage/toPrevPage\n    return 1;\n}","typeGuard":"static boolean isPageNumber(String s) {\n    return s != null && s.matches(\"\\\\d+\") && Integer.parseInt(s) > 0;\n}","tryCatchPattern":null,"preventionTips":["Constrain permalink route patterns so only \\d+ reaches the page slot.","Validate page params at the controller/router boundary and 404 on non-numeric values.","Audit theme next/prev link generation to always emit integers."],"tags":["pagination","theme-router","url-parsing","user-input"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}