NationalSecurityAgency/ghidra · error · RuntimeError

port must be numeric

Error message

port must be numeric

What it means

Raised by ghidra_trace_connect() (commands.py:184-185) when int(port) raises ValueError after the host:port split succeeded. The host part passed shape validation but the port token is not a base-10 integer.

Source

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

    """

    STATE.require_no_client()
    if address is None:
        raise RuntimeError(
            "'ghidra_trace_connect': missing required argument 'address'")

    parts = address.split(':')
    if len(parts) != 2:
        raise RuntimeError("address must be in the form 'host:port'")
    host, port = parts
    try:
        c = socket.socket()
        c.connect((host, int(port)))
        # TODO: Can we get version info from the DLL?
        STATE.client = Client(c, "dbgeng.dll", methods.REGISTRY)
        print(f"Connected to {STATE.client.description} at {address}")
    except ValueError:
        raise RuntimeError("port must be numeric")


def ghidra_trace_listen(address: str = '127.0.0.1:0') -> None:
    """Listen for Ghidra to connect for tracing.

    Takes an optional address for the host and port on which to listen.
    Either the form 'host:port' or just 'port'. If omitted, it will bind
    to an ephemeral port on localhost. If only the port is given, it will
    bind to that port on localhost. This command will block until the
    connection is established.
    """

    STATE.require_no_client()
    parts = address.split(':')
    if len(parts) == 1:
        host, port = '127.0.0.1', parts[0]
    elif len(parts) == 2:
        host, port = parts

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Strip the port and ensure it is a plain decimal integer in 0..65535.
  2. Validate port with int(port) in a guard before calling connect (see validationCode).
  3. Remove any '/protocol' suffix or whitespace from the value.

Example fix

// before
ghidra_trace_connect('127.0.0.1:8080/tcp')   # ValueError -> port must be numeric

// after
port = '8080/tcp'.split('/')[0].strip()
ghidra_trace_connect(f'127.0.0.1:{int(port)}')
Defensive patterns

Strategy: validation

Validate before calling

def parse_port(token):
    try:
        p = int(token)
    except (TypeError, ValueError):
        raise ValueError(f'port must be numeric, got {token!r}')
    if not 0 <= p <= 65535:
        raise ValueError('port out of range')
    return p

host, port = address.split(':')
parse_port(port)   # raises before connect if invalid

Type guard

def port_is_numeric(token) -> bool:
    try:
        return 0 <= int(token) <= 65535
    except (TypeError, ValueError):
        return False

Try / catch

try:
    ghidra_trace_connect(address)
except RuntimeError as e:
    if 'port must be numeric' in str(e):
        raise ValueError('strip non-numeric suffixes from the port') from e
    raise

Prevention

When it happens

Trigger: Passing 'host:abc', 'host:12.5', 'host:-' or any non-numeric port; port containing trailing whitespace or a unit like '8080/tcp'; empty port string 'host:'.

Common situations: Config sourced the port from an env var as a float string; copy/paste that included '/tcp' suffix; locale/formatting artifacts in the port field.

Related errors


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