opendataloader-project/opendataloader-pdf · error · IllegalArgumentException

Invalid page range format: '%s'. Expected format: 1,3,5-7

Error message

Invalid page range format: '%s'. Expected format: 1,3,5-7

What it means

parsePageRanges splits the --pages value on ',' and rejects any comma-separated token that is empty after trim. This catches consecutive commas, a leading comma, a trailing comma, and an entirely blank input. The whole original input string is reported, not just the bad token.

Source

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

        }
        return new ArrayList<>(cachedPageNumbers);
    }

    /**
     * Parses a page range specification into a list of page numbers.
     *
     * @param pages The page specification (e.g., "1,3,5-7").
     * @return List of 1-based page numbers.
     * @throws IllegalArgumentException if the format is invalid.
     */
    private static List<Integer> parsePageRanges(String pages) {
        List<Integer> result = new ArrayList<>();
        String[] parts = pages.split(",");

        for (String part : parts) {
            String trimmed = part.trim();
            if (trimmed.isEmpty()) {
                throw new IllegalArgumentException(String.format(INVALID_PAGE_RANGE_FORMAT, pages));
            }

            if (trimmed.contains("-")) {
                parseRange(trimmed, pages, result);
            } else {
                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));
        }

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Sanitize the input: trim and drop empty tokens before joining (e.g. filter out blanks).
  2. Validate the whole string with a regex like ^(\d+|\d+-\d+)(,(\d+|\d+-\d+))*$ before calling setPages.
  3. Reject a blank/whitespace-only value upstream instead of forwarding it to setPages.

Example fix

// before: config.setPages(String.join(",", userTokens));   // fails if a token is blank
// after:  config.setPages(userTokens.stream().map(String::trim).filter(s -> !s.isEmpty()).collect(joining(",")));
Defensive patterns

Strategy: validation

Validate before calling

// Reject empty/blank tokens and the empty string before calling setPages.
String pages = rawPages == null ? null : rawPages.trim();
if (pages == null || pages.isEmpty()) {
    throw new IllegalArgumentException("--pages must not be blank");
}
for (String t : pages.split(",")) {
    if (t.trim().isEmpty()) throw new IllegalArgumentException(
        "--pages has an empty token (consecutive/trailing comma): " + pages);
}
config.setPages(pages);

Type guard

static final java.util.regex.Pattern PAGES =
    java.util.regex.Pattern.compile("^(\\d+|\\d+-\\d+)(,(\\d+|\\d+-\\d+))*$");
static boolean isValidPagesSpec(String s) {
    return s != null && PAGES.matcher(s.trim()).matches();
}

Try / catch

try {
    config.setPages(raw);
} catch (IllegalArgumentException e) {
    // report the expected format 1,3,5-7 and abort input handling
}

Prevention

When it happens

Trigger: config.setPages("1,,3"), config.setPages("1,2,"), config.setPages(",1"), or config.setPages("") (splitting "" yields one empty token).

Common situations: Dynamically building the range string with String.join and an empty list element; trailing comma from user input; blank value passed from an unset env var.

Related errors


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