{"record":{"id":"1a01815bbc106229","repo":"NationalSecurityAgency/ghidra","slug":"value-address-does-not-evaluate-to-an-int","errorCode":null,"errorMessage":"Value '{address}' does not evaluate to an int","messagePattern":"Value '(.+?)' does not evaluate to an int","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py","lineNumber":560,"sourceCode":"def eval_address(address: Union[str, int]) -> int:\n    try:\n        result = util.parse_and_eval(address)\n        if isinstance(result, int):\n            return result\n        raise ValueError(f\"Value '{address}' does not evaluate to an int\")\n    except Exception:\n        raise RuntimeError(f\"Cannot convert '{address}' to address\")\n\n\ndef eval_range(address: Union[str, int],\n               length: Union[str, int]) -> Tuple[int, int]:\n    start = eval_address(address)\n    try:\n        l = util.parse_and_eval(length)\n    except Exception as e:\n        raise RuntimeError(f\"Cannot convert '{length}' to length\")\n    if not isinstance(l, int):\n        raise ValueError(f\"Value '{address}' does not evaluate to an int\")\n    end = start + l\n    return start, end\n\n\ndef putmem(address: Union[str, int], length: Union[str, int],\n           pages: bool = True, display_result: bool = True) -> Dict[str, int]:\n    start, end = eval_range(address, length)\n    return put_bytes(start, end, pages, display_result)\n\n\ndef ghidra_trace_putmem(address: Union[str, int], length: Union[str, int],\n                        pages: bool = True) -> Dict[str, int]:\n    \"\"\"Record the given block of memory into the Ghidra trace.\"\"\"\n\n    STATE.require_tx()\n    return putmem(address, length, pages, True)\n\n","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py#L542-L578","documentation":"Raised by eval_range() (commands.py:559-560) when parse_and_eval(length) succeeded but returned a non-int (e.g. a string, float, or None). The length resolved to a value but not to an integer usable as a byte count. Note the f-string uses {address} (likely a copy-paste bug) so the message names the address rather than the offending length.","triggerScenarios":"parse_and_eval returning a type other than int for the length argument; passing a length expression that evaluates to a string or float; some dbgeng evaluators returning variant types for certain expressions.","commonSituations":"Length expression that resolves to a symbol value with type metadata instead of a raw number; evaluator returning a Python wrapper object that fails isinstance(int); edge cases in pybag/dbgmodel bridging.","solutions":["Coerce or pass length as a plain int literal (e.g. 0x100) rather than a typed expression.","If a typed value is unavoidable, pre-convert: int(util.parse_and_eval(length)) inside a try, then pass the int.","Report the upstream evaluator quirk if it persists — the message names address but the culprit is the length operand."],"exampleFix":"// before\nghidra_trace_putmem(addr, 'some_typed_expr')   # non-int result\n\n// after\nlength = util.parse_and_eval('some_typed_expr')\nif not isinstance(length, int):\n    length = int(length)\nghidra_trace_putmem(addr, length)","handlingStrategy":"type-guard","validationCode":"def coerce_length(expr):\n    val = util.parse_and_eval(expr)\n    if not isinstance(val, int):\n        val = int(val)\n    return val\n\nlength = coerce_length(length_expr)\nghidra_trace_putmem(address, length)","typeGuard":"def length_is_int(expr) -> bool:\n    try:\n        return isinstance(util.parse_and_eval(expr), int)\n    except Exception:\n        return False","tryCatchPattern":"try:\n    ghidra_trace_putmem(address, length)\nexcept (RuntimeError, ValueError) as e:\n    if 'does not evaluate to an int' in str(e):\n        length = int(util.parse_and_eval(length))\n        ghidra_trace_putmem(address, length)\n    else:\n        raise","preventionTips":["Coerce evaluator results to int at the boundary.","Pass plain int literals to avoid typed-return quirks.","Note the message names address but the culprit is the length operand."],"tags":["expression-eval","type-mismatch","memory","ghidra"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}