NationalSecurityAgency/ghidra · error · RuntimeError

No trace active

Error message

No trace active

What it means

Thrown by State.require_trace() when no trace object is active — ghidra_trace_start has not been called or the trace was reset. Commands that operate on a trace (e.g., creating snapshots, recording memory/registers) require an active Trace[Extra] object. This RuntimeError indicates the trace lifecycle hasn't been initiated.

Source

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

    def __init__(self) -> None:
        self.reset_client()

    def require_client(self) -> Client:
        if self.client is None:
            raise RuntimeError("Not connected")
        return self.client

    def require_no_client(self) -> None:
        if self.client != None:
            raise RuntimeError("Already connected")

    def reset_client(self) -> None:
        self.client: Optional[Client] = None
        self.reset_trace()

    def require_trace(self) -> Trace[Extra]:
        if self.trace is None:
            raise RuntimeError("No trace active")
        return self.trace

    def require_no_trace(self) -> None:
        if self.trace != None:
            raise RuntimeError("Trace already started")

    def reset_trace(self) -> None:
        self.trace: Optional[Trace[Extra]] = None
        util.set_convenience_variable('_ghidra_tracing', "false")
        self.reset_tx()

    def require_tx(self) -> Tuple[Trace, Transaction]:
        trace = self.require_trace()
        if self.tx is None:
            raise RuntimeError("No transaction")
        return trace, self.tx

    def require_no_tx(self) -> None:

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Call ghidra_trace_start('trace_name') to create and activate a trace before recording commands.
  2. Ensure the trace connector is connected first (ghidra_trace_connect) — starting a trace requires a client.
  3. Check if reset_trace was called unexpectedly and re-start the trace.
  4. In scripts, follow the lifecycle: connect > start trace > begin tx > record > end tx > stop trace > disconnect.

Example fix

# Before: recording without an active trace
# ghidra_trace_putmem(...)
#
# After: start trace first
# ghidra_trace_connect('127.0.0.1:12345')
# ghidra_trace_start('mytrace')
# ghidra_trace_putmem(...)
Defensive patterns

Strategy: validation

Validate before calling

# Before trace-recording commands, verify a trace is active:
if STATE.trace is None:
    ghidra_trace_connect('127.0.0.1:12345')
    ghidra_trace_start('mytrace')
# now safe to issue recording commands

Type guard

def has_active_trace(state) -> bool:
    return state.trace is not None

Try / catch

try:
    trace = STATE.require_trace()
except RuntimeError as e:
    if str(e) == 'No trace active':
        ghidra_trace_start('mytrace')
        trace = STATE.require_trace()
    else:
        raise

Prevention

When it happens

Trigger: STATE.require_trace() is called by trace-recording commands, but STATE.trace is None (from reset_trace or initial state). Happens when commands like ghidra_trace_putmem, ghidra_trace_tx_start are issued before ghidra_trace_start was called to create the trace.

Common situations: The user forgot to call ghidra_trace_start('path') before recording. The trace was reset via reset_trace() (which sets trace to None) and not re-established. Script execution skips the start step.

Related errors


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