apache/beam · error · IllegalArgumentException
Work completed and work remaining must be greater than or eq
Error message
Work completed and work remaining must be greater than or equal to zero but were %s and %s.
What it means
RestrictionTracker.Progress.from builds an immutable progress snapshot. It validates that workCompleted and workRemaining are non-negative; a negative value throws IllegalArgumentException with both numbers in the message. This guards the contract documented on the method's parameters.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/splittabledofn/RestrictionTracker.java:191
* A representation for the amount of known completed and remaining work. See {@link
* HasProgress#getProgress()} for details.
*/
@AutoValue
public abstract static class Progress {
/** Constant Progress instance to be used when no work has been completed yet. */
public static final Progress NONE = from(0, 1);
/**
* A representation for the amount of known completed and remaining work. See {@link
* HasProgress#getProgress()} for details.
*
* @param workCompleted Must be {@code >= 0}.
* @param workRemaining Must be {@code >= 0}.
*/
public static Progress from(double workCompleted, double workRemaining) {
if (workCompleted < 0 || workRemaining < 0) {
throw new IllegalArgumentException(
String.format(
"Work completed and work remaining must be greater than or equal to zero but were %s and %s.",
workCompleted, workRemaining));
}
return new AutoValue_RestrictionTracker_Progress(workCompleted, workRemaining);
}
/** The known amount of completed work. */
public abstract double getWorkCompleted();
/** The known amount of work remaining. */
public abstract double getWorkRemaining();
}
/** A representation of the truncate result. */
@AutoValue
public abstract static class TruncateResult<RestrictionT> {
/** Returns a {@link TruncateResult} for the given restriction. */View on GitHub (pinned to 12126d8942)
Solutions
- Clamp computed values: Math.max(0, workCompleted) and Math.max(0, workRemaining) before calling from()
- Audit the custom tracker's progress math for underflow or wrong ordering of subtraction operands
- Validate restriction size > 0 when constructing the tracker so progress never goes negative
- Handle NaN/rounding explicitly if work is derived from floating-point positions
Example fix
// before double done = position - startPos; // can be negative on wrap-around return Progress.from(done, endPos - position); // after double done = Math.max(0, position - startPos); double remaining = Math.max(0, endPos - position); return Progress.from(done, remaining);
Defensive patterns
Strategy: validation
Validate before calling
if (workCompleted < 0 || workRemaining < 0 || Double.isNaN(workCompleted) || Double.isNaN(workRemaining)) {
throw new IllegalArgumentException("progress must be non-negative");
} Type guard
static boolean isValidProgress(double done, double remaining) {
return done >= 0 && remaining >= 0 && !Double.isNaN(done) && !Double.isNaN(remaining);
} Try / catch
try {
return Progress.from(done, remaining);
} catch (IllegalArgumentException e) {
return Progress.from(0, 0); // or clamp inputs and retry
} Prevention
- Clamp all computed progress values with Math.max(0, x)
- Check subtraction order in custom tracker progress math
- Unit-test custom RestrictionTracker.getProgress at boundary positions
When it happens
Trigger: Calling RestrictionTracker.Progress.from(x, y) with x < 0 or y < 0, typically from a custom RestrictionTracker.getProgress() implementation computing negative work (e.g. subtraction underflow or NaN-adjacent logic bugs).
Common situations: Implementing a custom RestrictionTracker where the work-completed calculation subtracts a larger value from a smaller one; float rounding producing negative residuals; misconfigured restriction sizes.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- offset is negative:
- offset exceeds the buffer limit. offset: , limit:
- length is negative:
- offset + length exceeds the buffer limit. offset: , length:
- Unknown type of fn class %s
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b60927ffd209b454.
Report an issue: GitHub.