NationalSecurityAgency/ghidra · error · ValueError
min cannot exceed max
Error message
min cannot exceed max
What it means
Thrown by the Python ghidratrace Lifespan dataclass's __post_init__ when min > max, except for the special empty-span case (min == 0 and max == -1) which represents an empty Lifespan. A span where the lower bound exceeds the upper bound is logically invalid.
Source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py:120
return self.max - self.min + 1
LIFESPAN_MIN = -1 << 63
LIFESPAN_MAX = (1 << 63) - 1
@dataclass(frozen=True)
class Lifespan:
min: int = LIFESPAN_MIN
max: int = LIFESPAN_MAX
def __post_init__(self) -> None:
if self.min < LIFESPAN_MIN:
raise ValueError("min out of range of int64")
if self.max > LIFESPAN_MAX:
raise ValueError("max out of range of int64")
if self.min > self.max and not (self.min == 0 and self.max == -1):
raise ValueError("min cannot exceed max")
def is_empty(self) -> bool:
return self.min == 0 and self.max == -1
def __str__(self) -> str:
if self.is_empty():
return "(EMPTY)"
min = '(-inf' if self.min == LIFESPAN_MIN else f'[{self.min}'
max = '+inf)' if self.max == LIFESPAN_MAX else f'{self.max}]'
return f'{min},{max}'
def __repr__(self) -> str:
return 'Lifespan' + self.__str__()
@dataclass
class Schedule:
"""A more constrained form of TraceSchedule from our Java code.View on GitHub (pinned to d5f144c24d)
Solutions
- Order the bounds so min <= max when constructing, or use the explicit empty span Lifespan(0, -1) for empty.
- If bounds may arrive in either order, normalize: mn, mx = sorted([a, b]).
- Use the is_empty() idiom (0, -1) deliberately rather than passing an arbitrary inverted pair.
Example fix
# before span = Lifespan(min=end_snap, max=start_snap) # swapped # after mn, mx = min(start_snap, end_snap), max(start_snap, end_snap) span = Lifespan(min=mn, max=mx)
Defensive patterns
Strategy: validation
Validate before calling
mn, mx = min(start, end), max(start, end) span = Lifespan(min=mn, max=mx)
Type guard
def ordered(mn: int, mx: int) -> bool:
return mn <= mx or (mn == 0 and mx == -1) Try / catch
try:
span = Lifespan(min=lo, max=hi)
except ValueError:
lo, hi = min(lo, hi), max(lo, hi)
span = Lifespan(min=lo, max=hi) Prevention
- Normalize bounds so min <= max before constructing Lifespan.
- Use Lifespan(0, -1) deliberately to represent the empty span.
- Double-check argument order: min first, max second.
When it happens
Trigger: Constructing Lifespan(min=a, max=b) with a > b (and not the (0, -1) empty case), e.g. swapping min/max arguments or computing a range that inverted.
Common situations: Argument order swapped (max passed as min); start/end snaps computed such that start > end; off-by-one in schedule parsing producing an inverted range.
Related errors
- min out of range of int64
- max out of range of int64
- {object} is not {err_msg}
- No saved offers to launch {}
- Range [%s:%x+%x] entirely exceeds space min
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/e512a6cebd131b89.
Report an issue: GitHub.