{"record":{"id":"328fa93396939c23","repo":"opendataloader-project/opendataloader-pdf","slug":"invalid-timeout-value-s-must-be-a-non-negative","errorCode":null,"errorMessage":"Invalid timeout value '%s'. Must be a non-negative integer.","messagePattern":"Invalid timeout value '(.+?)'\\. Must be a non-negative integer\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/api/cli/CLIOptions.java","lineNumber":699,"sourceCode":"        if (commandLine.hasOption(HYBRID_OCR_LONG_OPTION)) {\n            // Deprecated: OCR settings are now configured on the hybrid server\n            System.err.println(\"Warning: --hybrid-ocr is deprecated. \"\n                    + \"Configure OCR settings on the hybrid server instead (--ocr-lang, --force-ocr).\");\n        }\n        if (commandLine.hasOption(HYBRID_URL_LONG_OPTION)) {\n            String url = commandLine.getOptionValue(HYBRID_URL_LONG_OPTION);\n            if (url != null && !url.trim().isEmpty()) {\n                config.getHybridConfig().setUrl(url.trim());\n            }\n        }\n        if (commandLine.hasOption(HYBRID_TIMEOUT_LONG_OPTION)) {\n            String timeoutValue = commandLine.getOptionValue(HYBRID_TIMEOUT_LONG_OPTION);\n            if (timeoutValue != null && !timeoutValue.trim().isEmpty()) {\n                try {\n                    int timeout = Integer.parseInt(timeoutValue.trim());\n                    config.getHybridConfig().setTimeoutMs(timeout);\n                } catch (NumberFormatException e) {\n                    throw new IllegalArgumentException(\n                            String.format(\"Invalid timeout value '%s'. Must be a non-negative integer.\", timeoutValue));\n                }\n            }\n        }\n        if (commandLine.hasOption(HYBRID_FALLBACK_LONG_OPTION)) {\n            config.getHybridConfig().setFallbackToJava(true);\n        }\n        if (commandLine.hasOption(HYBRID_HANCOM_AI_REGIONLIST_STRATEGY_LONG_OPTION)) {\n            String value = commandLine.getOptionValue(HYBRID_HANCOM_AI_REGIONLIST_STRATEGY_LONG_OPTION);\n            if (value != null && !value.trim().isEmpty()) {\n                String normalized = value.trim().toLowerCase(Locale.ROOT);\n                if (!HybridConfig.REGIONLIST_TABLE_FIRST.equals(normalized)\n                        && !HybridConfig.REGIONLIST_LIST_ONLY.equals(normalized)) {\n                    throw new IllegalArgumentException(String.format(\n                            \"Option --%s: unsupported value '%s'. Supported values: %s, %s\",\n                            HYBRID_HANCOM_AI_REGIONLIST_STRATEGY_LONG_OPTION, normalized,\n                            HybridConfig.REGIONLIST_TABLE_FIRST, HybridConfig.REGIONLIST_LIST_ONLY));\n                }","sourceCodeStart":681,"sourceCodeEnd":717,"githubUrl":"https://github.com/opendataloader-project/opendataloader-pdf/blob/a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8/java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/api/cli/CLIOptions.java#L681-L717","documentation":"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.","triggerScenarios":"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.","commonSituations":"Appending units (s/ms); assuming seconds when the unit is milliseconds; passing a millisecond value larger than 2.1 billion; decimal timeout.","solutions":["Pass a plain non-negative integer in milliseconds: `--hybrid-timeout 30000`.","Use `0` for no timeout (the default).","If you have seconds, multiply by 1000 and keep the result under 2147483647.","Strip any units or decimal points."],"exampleFix":"// before\nopendataloader-pdf doc.pdf --hybrid hancom-ai --hybrid-timeout 30s\n// after\nopendataloader-pdf doc.pdf --hybrid hancom-ai --hybrid-timeout 30000","handlingStrategy":"try-catch","validationCode":"String raw = commandLine.getOptionValue(\"hybrid-timeout\");\nif (raw != null && !raw.trim().isEmpty()) {\n    try {\n        int t = Integer.parseInt(raw.trim());\n        if (t < 0) throw new IllegalArgumentException(\"--hybrid-timeout must be >= 0\");\n        config.getHybridConfig().setTimeoutMs(t);\n    } catch (NumberFormatException e) {\n        throw new IllegalArgumentException(\"--hybrid-timeout must be an int (ms): \" + raw, e);\n    }\n}","typeGuard":"boolean isAcceptableTimeout(String raw) {\n    try {\n        int t = Integer.parseInt(raw.trim());\n        return t >= 0;\n    } catch (NumberFormatException e) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    config.getHybridConfig().setTimeoutMs(Integer.parseInt(raw.trim()));\n} catch (NumberFormatException e) {\n    throw new IllegalArgumentException(\"--hybrid-timeout must be a non-negative int milliseconds\", e);\n} catch (IllegalArgumentException e) {\n    // setTimeoutMs rejects negatives with 'Timeout must be non-negative'\n    throw e;\n}","preventionTips":["Pass milliseconds as a plain integer (0 = no timeout).","Keep the value under 2147483647 (int max); do not pass seconds or larger units.","Validate programmatically and give a clearer message than the generic one."],"tags":["cli","hybrid-timeout","validation","numeric","integer-overflow"],"backgroundTag":null,"analyzedSha":"a7789b8e77dd05e2b8659eb3ea12fc458f80bfb8","analyzedAt":"2026-08-14T05:22:03.953Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}