halo-dev/halo · warning · IllegalArgumentException

Page number must be a number

Error message

Page number must be a number

What it means

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.

Source

Thrown at api/src/main/java/run/halo/app/theme/router/PageUrlUtils.java:104

        return Objects.toString(path, "/");
    }

    private static String appendPagePart(String path, long page) {
        return PathUtils.combinePath(path, PAGE_PART, String.valueOf(page));
    }

    private static String toNextPage(String pageStr, long total) {
        long page = Math.min(parseInt(pageStr) + 1, Math.max(total, 1));
        return String.valueOf(page);
    }

    private static int toPrevPage(String pageStr) {
        return Math.max(parseInt(pageStr) - 1, 1);
    }

    private static int parseInt(String pageStr) {
        if (!NumberUtils.isParsable(pageStr)) {
            throw new IllegalArgumentException("Page number must be a number");
        }
        return NumberUtils.toInt(pageStr, 1);
    }
}

View on GitHub (pinned to d2f5165f9c)

Solutions

  1. Correct the page segment in the URL to an integer (e.g. /page/2/).
  2. If you control permalink rules, ensure only \d+ can land in the page position.
  3. Return a 404 for non-numeric page paths at the routing layer instead of letting parseInt throw.
  4. Audit theme templates that construct next/prev links to always emit numeric page values.
Defensive patterns

Strategy: validation

Validate before calling

if (!NumberUtils.isParsable(pageStr)) {
    // return 404 / default page 1 instead of calling toNextPage/toPrevPage
    return 1;
}

Type guard

static boolean isPageNumber(String s) {
    return s != null && s.matches("\\d+") && Integer.parseInt(s) > 0;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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/.


AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14). Data as JSON: /api/errors/d20eab0862003190. Report an issue: GitHub.