NationalSecurityAgency/ghidra · error · RuntimeError

Trace already started

Error message

Trace already started

What it means

Raised by State.require_no_trace when STATE.trace is not None (a trace already exists). This guard prevents starting a second trace over an existing one; 'ghidra trace start' calls require_no_trace to ensure no active trace is present.

Source

Thrown at Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py:136

            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:
        if self.tx != None:
            raise RuntimeError("Transaction already started")

    def reset_tx(self) -> None:
        self.tx: Optional[Transaction] = None

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Stop or reset the existing trace before starting a new one (e.g. disconnect and reconnect, which resets trace).
  2. Check STATE.trace is None before calling start_trace.
  3. Call STATE.reset_trace() or STATE.reset_client() to clear the old trace if it is stale.

Example fix

# before: start while trace active
ghidra_trace_start()  # first trace
ghidra_trace_start()  # Trace already started

# after: clear first
if STATE.trace is not None:
    STATE.reset_trace()
ghidra_trace_start()
Defensive patterns

Strategy: validation

Validate before calling

if STATE.trace is not None:
    raise RuntimeError("Trace already started; disconnect or reset before starting a new trace")

Type guard

def has_no_trace() -> bool:
    return STATE.trace is None

Try / catch

try:
    ghidra_trace_start()
except RuntimeError:
    if 'Trace already started' in str(e):
        STATE.reset_trace()
        ghidra_trace_start()
    else:
        raise

Prevention

When it happens

Trigger: 'ghidra trace start' (or start_trace) is called when STATE.trace already holds an active Trace. The require_no_trace guard fires because a trace is already active.

Common situations: User ran 'ghidra trace start' twice without stopping the first trace. The previous trace was not properly stopped or reset. The script re-ran without cleanup after an error.

Related errors


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