NationalSecurityAgency/ghidra · error · RuntimeError

Cannot convert '{length}' to length

Error message

Cannot convert '{length}' to length

What it means

Raised by eval_range() (commands.py:555-558) when util.parse_and_eval(length) throws while resolving the length operand. It is the length-side counterpart of the address error: the start address resolved fine, but the length expression (symbol/number) could not be evaluated to any value.

Source

Thrown at Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py:558


def eval_address(address: Union[str, int]) -> int:
    try:
        result = util.parse_and_eval(address)
        if isinstance(result, int):
            return result
        raise ValueError(f"Value '{address}' does not evaluate to an int")
    except Exception:
        raise RuntimeError(f"Cannot convert '{address}' to address")


def eval_range(address: Union[str, int],
               length: Union[str, int]) -> Tuple[int, int]:
    start = eval_address(address)
    try:
        l = util.parse_and_eval(length)
    except Exception as e:
        raise RuntimeError(f"Cannot convert '{length}' to length")
    if not isinstance(l, int):
        raise ValueError(f"Value '{address}' does not evaluate to an int")
    end = start + l
    return start, end


def putmem(address: Union[str, int], length: Union[str, int],
           pages: bool = True, display_result: bool = True) -> Dict[str, int]:
    start, end = eval_range(address, length)
    return put_bytes(start, end, pages, display_result)


def ghidra_trace_putmem(address: Union[str, int], length: Union[str, int],
                        pages: bool = True) -> Dict[str, int]:
    """Record the given block of memory into the Ghidra trace."""

    STATE.require_tx()
    return putmem(address, length, pages, True)

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Verify the length expression evaluates standalone with '? <expr>' in the debugger.
  2. Pass an integer literal (e.g. 0x100) for length to avoid symbol resolution.
  3. Check the evaluator syntax/mode and that referenced symbols are loaded.

Example fix

// before
ghidra_trace_putmem(0x140001000, 'mytype!cb')

// after
ghidra_trace_putmem(0x140001000, 0x100)
# or verify 'mytype!cb' resolves first
Defensive patterns

Strategy: try-catch

Validate before calling

def resolve_length_safe(expr):
    try:
        v = util.parse_and_eval(expr)
    except Exception:
        return None
    return v

length_val = resolve_length_safe(length)
if length_val is None:
    raise ValueError(f'cannot resolve length {length!r}')

Type guard

def length_resolves(expr) -> bool:
    try:
        util.parse_and_eval(expr)
        return True
    except Exception:
        return False

Try / catch

try:
    ghidra_trace_putmem(address, length)
except RuntimeError as e:
    if 'Cannot convert' in str(e) and 'to length' in str(e):
        raise ValueError(f'unresolvable length: {length!r}') from e
    raise

Prevention

When it happens

Trigger: Calling ghidra_trace_putmem(addr, 'sizeof_bogus') with an undefined symbol; passing a malformed length expression; resolving length against a module not currently loaded.

Common situations: Typo in a sizeof/symbol expression; using a C++ expression in MASM mode or vice versa; length expressed as a symbol from a not-yet-loaded header.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/d964672dcf6bc211. Report an issue: GitHub.