opendataloader-project/opendataloader-pdf · error · IllegalArgumentException

Page numbers must be positive: '%s'

Error message

Page numbers must be positive: '%s'

What it means

parseRange successfully parses both bounds as integers but at least one is < 1. Pages are 1-based, so 0 (or anything negative that survives parseInt, e.g. via a leading sign) is rejected as non-positive.

Source

Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/api/Config.java:775

                parseSinglePage(trimmed, pages, result);
            }
        }

        return result;
    }

    private static void parseRange(String range, String fullInput, List<Integer> result) {
        String[] parts = range.split("-", SPLIT_KEEP_EMPTY_TRAILING);
        if (parts.length != 2 || parts[0].isEmpty() || parts[1].isEmpty()) {
            throw new IllegalArgumentException(String.format(INVALID_PAGE_RANGE_FORMAT, fullInput));
        }

        try {
            int start = Integer.parseInt(parts[0].trim());
            int end = Integer.parseInt(parts[1].trim());

            if (start < 1 || end < 1) {
                throw new IllegalArgumentException(
                    String.format("Page numbers must be positive: '%s'", fullInput));
            }
            if (start > end) {
                throw new IllegalArgumentException(
                    String.format("Invalid page range '%s': start page cannot be greater than end page", range));
            }

            for (int i = start; i <= end; i++) {
                result.add(i);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(String.format(INVALID_PAGE_RANGE_FORMAT, fullInput));
        }
    }

    private static void parseSinglePage(String page, String fullInput, List<Integer> result) {
        try {
            int pageNum = Integer.parseInt(page);

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Use 1-based page numbers; clamp computed bounds to a minimum of 1.
  2. When deriving ranges programmatically, guard start/end with Math.max(1, value).

Example fix

// before: config.setPages(zeroBasedStart + "-" + zeroBasedEnd);
// after:  config.setPages(Math.max(1, zeroBasedStart + 1) + "-" + Math.max(1, zeroBasedEnd + 1));
Defensive patterns

Strategy: validation

Validate before calling

for (String t : pages.split(",")) {
    if (t.contains("-")) {
        String[] h = t.split("-", -1);
        if (Integer.parseInt(h[0].trim()) < 1 || Integer.parseInt(h[1].trim()) < 1)
            throw new IllegalArgumentException("Page numbers must be 1-based: " + t);
    }
}
config.setPages(pages);

Try / catch

try { config.setPages(raw); }
catch (IllegalArgumentException e) { /* clamp/reprompt with 1-based numbers */ }

Prevention

When it happens

Trigger: config.setPages("0-5"), config.setPages("1-0"), config.setPages("0-0").

Common situations: Off-by-one from zero-indexed logic fed directly into a 1-based option; negative value from a subtraction that underflows.

Related errors


AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14). Data as JSON: /api/errors/96295e05e2c3e020. Report an issue: GitHub.