NationalSecurityAgency/ghidra · error · IllegalArgumentException
max < min: min={min},max={max}
Error message
max < min: min={min},max={max} What it means
Thrown by Lifespan.Domain.closed(long min, long max): a lifespan is an inclusive snapshot-key range [min,max], so max < min is an empty/invalid span. Ghidra treats the minimum snapshot key as the lower bound, so an inverted range is a programming error rather than an empty-range request.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/Lifespan.java:143
return EMPTY;
}
return DOMAIN.atMost(DOMAIN.dec(snap));
}
/**
* The domain of snapshot keys
*/
public enum Domain implements Span.Domain<Long, Lifespan> {
INSTANCE;
@Override
public Lifespan closed(Long min, Long max) {
return closed(min.longValue(), max.longValue());
}
public Lifespan closed(long min, long max) {
if (max < min) {
throw new IllegalArgumentException("max < min: min=" + min + ",max=" + max);
}
return new Impl(min, max);
}
@Override
public Lifespan newSpan(Long min, Long max) {
return new Impl(min, max);
}
public Lifespan value(long n) {
return new Impl(n, n);
}
@Override
public Lifespan atMost(Long max) {
return atMost(max.longValue());
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Order the bounds before constructing: long lo = Math.min(a, b), hi = Math.max(a, b); then Lifespan.closed(lo, hi).
- Verify the caller's snapshot keys are in ascending order.
- If an empty result is intended, handle that case explicitly rather than passing an inverted range.
- Add an assertion/unit test on the span constructor inputs.
Example fix
// before Lifespan span = Lifespan.span(fromSnap, toSnap); // toSnap < fromSnap // after long lo = Math.min(fromSnap, toSnap); long hi = Math.max(fromSnap, toSnap); Lifespan span = Lifespan.span(lo, hi);
Defensive patterns
Strategy: validation
Validate before calling
long lo = Math.min(a, b), hi = Math.max(a, b); Lifespan span = Lifespan.span(lo, hi);
Type guard
static boolean validSpan(long min, long max) { return max >= min; } Prevention
- Order snapshot-key bounds before constructing a Lifespan.
- Validate ascending order at the boundary where user/external keys enter.
- Handle 'empty range' as an explicit case rather than an inverted span.
When it happens
Trigger: Constructing a Lifespan via Domain.INSTANCE.closed(min, max), Lifespan.closed(...), or any code path that builds a span from two keys where the 'max' key is smaller than the 'min' key (e.g. interchanged arguments, or a computed end that came before the start).
Common situations: Swapping min/max arguments; computing max from a sub-snapshot's parent where ordering is inverted; passing user-supplied from/to snapshot indices without ordering; off-by-one in span arithmetic.
Related errors
- endpoint cannot be -1
- Another mapping would conflict
- Given bookmark is not present at this view's snap
- operandIndex
- Memory addresses cannot be associated with a thread
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/14c086491514982f.
Report an issue: GitHub.