{"record":{"id":"2db289a57ae40220","repo":"NationalSecurityAgency/ghidra","slug":"min-out-of-range-of-int64","errorCode":null,"errorMessage":"min out of range of int64","messagePattern":"min out of range of int64","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py","lineNumber":116,"sourceCode":"    def extend(cls, min: Address, length: int) -> 'AddressRange':\n        return cls(min.space, min.offset, min.offset + length - 1)\n\n    def length(self) -> int:\n        return self.max - self.min + 1\n\n\nLIFESPAN_MIN = -1 << 63\nLIFESPAN_MAX = (1 << 63) - 1\n\n\n@dataclass(frozen=True)\nclass Lifespan:\n    min: int = LIFESPAN_MIN\n    max: int = LIFESPAN_MAX\n\n    def __post_init__(self) -> None:\n        if self.min < LIFESPAN_MIN:\n            raise ValueError(\"min out of range of int64\")\n        if self.max > LIFESPAN_MAX:\n            raise ValueError(\"max out of range of int64\")\n        if self.min > self.max and not (self.min == 0 and self.max == -1):\n            raise ValueError(\"min cannot exceed max\")\n\n    def is_empty(self) -> bool:\n        return self.min == 0 and self.max == -1\n\n    def __str__(self) -> str:\n        if self.is_empty():\n            return \"(EMPTY)\"\n        min = '(-inf' if self.min == LIFESPAN_MIN else f'[{self.min}'\n        max = '+inf)' if self.max == LIFESPAN_MAX else f'{self.max}]'\n        return f'{min},{max}'\n\n    def __repr__(self) -> str:\n        return 'Lifespan' + self.__str__()\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py#L98-L134","documentation":"Thrown by the Python ghidratrace Lifespan dataclass's __post_init__ when the `min` field is below LIFESPAN_MIN (-2**63, the smallest signed 64-bit value). Lifespan snap numbers are transmitted to the Java side as int64, so the client validates bounds before sending.","triggerScenarios":"Constructing Lifespan(min=...) with a value less than -9223372036854775808, e.g. from arithmetic that underflows or from an incorrectly computed offset.","commonSituations":"Subtracting a large snap delta from 0/snap 0 producing a value below int64 min; parsing a malformed schedule; passing a raw negative value by mistake.","solutions":["Clamp min to LIFESPAN_MIN (use the module constant) before constructing the Lifespan.","Re-check the arithmetic producing the snap number; treat snap 0 as the floor for live traces.","If you need the open-ended lower bound, pass LIFESPAN_MIN explicitly rather than computing it."],"exampleFix":"# before\nspan = Lifespan(min=base_snap - huge_delta)\n\n# after\nfrom ghidratrace.client import LIFESPAN_MIN\nlo = max(base_snap - huge_delta, LIFESPAN_MIN)\nspan = Lifespan(min=lo, max=base_snap)","handlingStrategy":"validation","validationCode":"from ghidratrace.client import LIFESPAN_MIN, Lifespan\nlo = max(value, LIFESPAN_MIN)\nspan = Lifespan(min=lo, max=LIFESPAN_MAX)","typeGuard":"def valid_min(v: int) -> bool:\n    from ghidratrace.client import LIFESPAN_MIN\n    return v >= LIFESPAN_MIN","tryCatchPattern":"try:\n    span = Lifespan(min=lo, max=hi)\nexcept ValueError:\n    lo = max(lo, LIFESPAN_MIN)\n    span = Lifespan(min=lo, max=hi)","preventionTips":["Clamp snap values to [LIFESPAN_MIN, LIFESPAN_MAX] before constructing Lifespan.","Use the module constants for open-ended bounds rather than computing them.","Treat snap 0 as the practical floor for live traces."],"tags":["python","lifespan","int64","validation","trace-rmi"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}