apache/dubbo · error · IllegalArgumentException
delta {delta} < 0
Error message
delta {delta} < 0 What it means
Thrown by AtomicPositiveInteger.getAndAdd when delta is negative. getAndAdd atomically adds delta and returns the prior value; a negative delta could drive the underlying field negative, breaking the non-negative masking guarantee, so it is rejected outright. Note that unlike AtomicInteger, this class forbids subtraction entirely.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/AtomicPositiveInteger.java:73
}
public final void set(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
INDEX_UPDATER.set(this, newValue);
}
public final int getAndSet(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("new value " + newValue + " < 0");
}
return INDEX_UPDATER.getAndSet(this, newValue) & Integer.MAX_VALUE;
}
public final int getAndAdd(int delta) {
if (delta < 0) {
throw new IllegalArgumentException("delta " + delta + " < 0");
}
return INDEX_UPDATER.getAndAdd(this, delta) & Integer.MAX_VALUE;
}
public final int addAndGet(int delta) {
if (delta < 0) {
throw new IllegalArgumentException("delta " + delta + " < 0");
}
return INDEX_UPDATER.addAndGet(this, delta) & Integer.MAX_VALUE;
}
public final boolean compareAndSet(int expect, int update) {
if (update < 0) {
throw new IllegalArgumentException("update value " + update + " < 0");
}
return INDEX_UPDATER.compareAndSet(this, expect, update);
}
View on GitHub (pinned to 3a3043227f)
Solutions
- Use decrementAndGet() or getAndDecrement() for subtraction — these mask the result to stay non-negative.
- If the delta is genuinely variable, split: if delta >= 0 use getAndAdd(delta), else call getAndDecrement() |delta| times or reconsider the data structure.
- Switch to AtomicInteger if negative values are legitimately needed.
Example fix
// before api.getAndAdd(-1); // throws // after api.getAndDecrement(); // non-negative masking built in
Defensive patterns
Strategy: validation
Validate before calling
int delta = /* ... */;
if (delta < 0) {
throw new IllegalArgumentException("getAndAdd needs delta >= 0; use getAndDecrement to subtract");
}
int prev = api.getAndAdd(delta); Type guard
static boolean isNonNegativeDelta(int d) { return d >= 0; } Prevention
- Use getAndDecrement() / decrementAndGet() for subtraction — they mask to non-negative.
- Never port AtomicInteger.getAndAdd(-n) directly; switch to the decrement methods.
- If variable deltas are needed, branch on sign before calling.
When it happens
Trigger: AtomicPositiveInteger.getAndAdd(delta) where delta < 0. Any code path that attempts to decrement via getAndAdd (rather than decrementAndGet, which masks the result) hits this guard.
Common situations: Porting code from AtomicInteger that used getAndAdd(-1) for decrementing; using a computed delta whose sign is wrong; generic algorithms that pass deltas that can go negative. This indicates the caller assumed AtomicInteger semantics.
Related errors
- new value {newValue} < 0
- update value {update} < 0
- expectedSize cannot be negative but was: {expectedSize}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/0317de1af2e96b36.
Report an issue: GitHub.