opendataloader-project/opendataloader-pdf · error · IllegalArgumentException
threads must be >= 1, got {threads}
Error message
threads must be >= 1, got {threads} What it means
Config.setThreads rejects any value < 1 with IllegalArgumentException, then caps the stored value to Runtime.getRuntime().availableProcessors(). The CLI path (applyThreadsOption) validates the requested value is >= 1 before calling setThreads, so this guard mainly fires for programmatic API callers passing 0 or a negative int. Passing 0 to mean 'auto' is not supported.
Source
Thrown at java/opendataloader-pdf-core/src/main/java/org/opendataloader/pdf/api/Config.java:930
private boolean outputStdout = false;
public boolean isOutputStdout() {
return outputStdout;
}
public void setOutputStdout(boolean outputStdout) {
this.outputStdout = outputStdout;
}
private int threads = 1;
public int getThreads() {
return threads;
}
public void setThreads(int threads) {
if (threads < 1) {
throw new IllegalArgumentException("threads must be >= 1, got " + threads);
}
this.threads = Math.min(threads, Runtime.getRuntime().availableProcessors());
}
/**
* Returns true if any output format requires structured content
* (reading order, heading levels, list detection, etc.).
* Text-only output does not need these expensive processing steps.
*/
public boolean needsStructuredProcessing() {
return isGenerateMarkdown() || isGenerateHtml() || isGenerateJSON() || isGeneratePDF();
}
/**
* Resolves conflicts between individually valid option values.
* Call once after all setters, before passing the Config to a processor.
* Currently: in hybrid mode, forces {@code threads} to 1 because the hybrid
* pipeline runs sequentially regardless of this value.View on GitHub (pinned to a7789b8e77)
Solutions
- Pass an integer >= 1.
- For 'auto' semantics, pass Runtime.getRuntime().availableProcessors() (setThreads will not increase it beyond that anyway).
- Guard computed counts: Math.max(1, cores - reserve).
Example fix
// before: config.setThreads(0); // intended 'auto' // after: config.setThreads(Runtime.getRuntime().availableProcessors());
Defensive patterns
Strategy: validation
Validate before calling
int requested = computeThreads();
if (requested < 1) {
requested = Runtime.getRuntime().availableProcessors(); // 'auto' fallback
}
config.setThreads(requested); Type guard
static boolean isValidThreads(int n) { return n >= 1; } Try / catch
try {
config.setThreads(n);
} catch (IllegalArgumentException e) {
config.setThreads(1); // safe default
} Prevention
- Never pass 0 to mean 'auto'; pass availableProcessors() instead.
- Guard derived counts with Math.max(1, cores - reserve).
When it happens
Trigger: Direct API call config.setThreads(0) or config.setThreads(-2); computing threads from a formula that can underflow to <= 0 (e.g. cores - 1 when cores == 1).
Common situations: Assuming 0 means 'use all cores'; deriving thread count from availableProcessors() - reserve and hitting zero on a single-core container.
Related errors
- Option --threads requires an integer >= 1, got '%s'
- Option --threads requires an integer >= 1, got %d
- Unsupported table method '%s'. Supported values: %s
- Unsupported reading order '%s'. Supported values: %s
- Unsupported image output mode '%s'. Supported values: %s
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/9c9c0a555dd77c77.
Report an issue: GitHub.