opendataloader-project/opendataloader-pdf · error · IllegalArgumentException

Invalid timeout value '%s'. Must be a non-negative integer.

Error message

Invalid timeout value '%s'. Must be a non-negative integer.

What it means

Thrown from the catch (NumberFormatException) block when Integer.parseInt cannot parse the --hybrid-timeout value. Note a subtlety: the message says 'Must be a non-negative integer' but this specific throw fires only on unparseable input (text, out-of-int-range, empty). A negative number like -5 parses fine here and instead fails later inside HybridConfig.setTimeoutMs with a different message ('Timeout must be non-negative'). A value exceeding Integer.MAX_VALUE (e.g. > 2147483647) also triggers this NumberFormatException. 0 means no timeout.

Source

Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/api/cli/CLIOptions.java:699

        if (commandLine.hasOption(HYBRID_OCR_LONG_OPTION)) {
            // Deprecated: OCR settings are now configured on the hybrid server
            System.err.println("Warning: --hybrid-ocr is deprecated. "
                    + "Configure OCR settings on the hybrid server instead (--ocr-lang, --force-ocr).");
        }
        if (commandLine.hasOption(HYBRID_URL_LONG_OPTION)) {
            String url = commandLine.getOptionValue(HYBRID_URL_LONG_OPTION);
            if (url != null && !url.trim().isEmpty()) {
                config.getHybridConfig().setUrl(url.trim());
            }
        }
        if (commandLine.hasOption(HYBRID_TIMEOUT_LONG_OPTION)) {
            String timeoutValue = commandLine.getOptionValue(HYBRID_TIMEOUT_LONG_OPTION);
            if (timeoutValue != null && !timeoutValue.trim().isEmpty()) {
                try {
                    int timeout = Integer.parseInt(timeoutValue.trim());
                    config.getHybridConfig().setTimeoutMs(timeout);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException(
                            String.format("Invalid timeout value '%s'. Must be a non-negative integer.", timeoutValue));
                }
            }
        }
        if (commandLine.hasOption(HYBRID_FALLBACK_LONG_OPTION)) {
            config.getHybridConfig().setFallbackToJava(true);
        }
        if (commandLine.hasOption(HYBRID_HANCOM_AI_REGIONLIST_STRATEGY_LONG_OPTION)) {
            String value = commandLine.getOptionValue(HYBRID_HANCOM_AI_REGIONLIST_STRATEGY_LONG_OPTION);
            if (value != null && !value.trim().isEmpty()) {
                String normalized = value.trim().toLowerCase(Locale.ROOT);
                if (!HybridConfig.REGIONLIST_TABLE_FIRST.equals(normalized)
                        && !HybridConfig.REGIONLIST_LIST_ONLY.equals(normalized)) {
                    throw new IllegalArgumentException(String.format(
                            "Option --%s: unsupported value '%s'. Supported values: %s, %s",
                            HYBRID_HANCOM_AI_REGIONLIST_STRATEGY_LONG_OPTION, normalized,
                            HybridConfig.REGIONLIST_TABLE_FIRST, HybridConfig.REGIONLIST_LIST_ONLY));
                }

View on GitHub (pinned to a7789b8e77)

Solutions

  1. Pass a plain non-negative integer in milliseconds: `--hybrid-timeout 30000`.
  2. Use `0` for no timeout (the default).
  3. If you have seconds, multiply by 1000 and keep the result under 2147483647.
  4. Strip any units or decimal points.

Example fix

// before
opendataloader-pdf doc.pdf --hybrid hancom-ai --hybrid-timeout 30s
// after
opendataloader-pdf doc.pdf --hybrid hancom-ai --hybrid-timeout 30000
Defensive patterns

Strategy: try-catch

Validate before calling

String raw = commandLine.getOptionValue("hybrid-timeout");
if (raw != null && !raw.trim().isEmpty()) {
    try {
        int t = Integer.parseInt(raw.trim());
        if (t < 0) throw new IllegalArgumentException("--hybrid-timeout must be >= 0");
        config.getHybridConfig().setTimeoutMs(t);
    } catch (NumberFormatException e) {
        throw new IllegalArgumentException("--hybrid-timeout must be an int (ms): " + raw, e);
    }
}

Type guard

boolean isAcceptableTimeout(String raw) {
    try {
        int t = Integer.parseInt(raw.trim());
        return t >= 0;
    } catch (NumberFormatException e) {
        return false;
    }
}

Try / catch

try {
    config.getHybridConfig().setTimeoutMs(Integer.parseInt(raw.trim()));
} catch (NumberFormatException e) {
    throw new IllegalArgumentException("--hybrid-timeout must be a non-negative int milliseconds", e);
} catch (IllegalArgumentException e) {
    // setTimeoutMs rejects negatives with 'Timeout must be non-negative'
    throw e;
}

Prevention

When it happens

Trigger: Pass `--hybrid-timeout 30s`, `--hybrid-timeout fast`, `--hybrid-timeout 5000000000` (exceeds int range), or `--hybrid-timeout 1.5` (decimal). Units suffixes and decimals are not supported.

Common situations: Appending units (s/ms); assuming seconds when the unit is milliseconds; passing a millisecond value larger than 2.1 billion; decimal timeout.

Understand the failure class

Related errors


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