{"record":{"id":"3af6f4c2ca7c8295","repo":"NationalSecurityAgency/ghidra","slug":"trace-already-started-3af6f4","errorCode":null,"errorMessage":"Trace already started","messagePattern":"Trace already started","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py","lineNumber":136,"sourceCode":"            raise RuntimeError(\"Not connected\")\n        return self.client\n\n    def require_no_client(self) -> None:\n        if self.client != None:\n            raise RuntimeError(\"Already connected\")\n\n    def reset_client(self) -> None:\n        self.client: Optional[Client] = None\n        self.reset_trace()\n\n    def require_trace(self) -> Trace[Extra]:\n        if self.trace is None:\n            raise RuntimeError(\"No trace active\")\n        return self.trace\n\n    def require_no_trace(self) -> None:\n        if self.trace != None:\n            raise RuntimeError(\"Trace already started\")\n\n    def reset_trace(self) -> None:\n        self.trace: Optional[Trace[Extra]] = None\n        util.set_convenience_variable('_ghidra_tracing', \"false\")\n        self.reset_tx()\n\n    def require_tx(self) -> Tuple[Trace, Transaction]:\n        trace = self.require_trace()\n        if self.tx is None:\n            raise RuntimeError(\"No transaction\")\n        return trace, self.tx\n\n    def require_no_tx(self) -> None:\n        if self.tx != None:\n            raise RuntimeError(\"Transaction already started\")\n\n    def reset_tx(self) -> None:\n        self.tx: Optional[Transaction] = None","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py#L118-L154","documentation":"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.","triggerScenarios":"'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.","commonSituations":"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.","solutions":["Stop or reset the existing trace before starting a new one (e.g. disconnect and reconnect, which resets trace).","Check STATE.trace is None before calling start_trace.","Call STATE.reset_trace() or STATE.reset_client() to clear the old trace if it is stale."],"exampleFix":"# before: start while trace active\nghidra_trace_start()  # first trace\nghidra_trace_start()  # Trace already started\n\n# after: clear first\nif STATE.trace is not None:\n    STATE.reset_trace()\nghidra_trace_start()","handlingStrategy":"validation","validationCode":"if STATE.trace is not None:\n    raise RuntimeError(\"Trace already started; disconnect or reset before starting a new trace\")","typeGuard":"def has_no_trace() -> bool:\n    return STATE.trace is None","tryCatchPattern":"try:\n    ghidra_trace_start()\nexcept RuntimeError:\n    if 'Trace already started' in str(e):\n        STATE.reset_trace()\n        ghidra_trace_start()\n    else:\n        raise","preventionTips":["Stop or reset the existing trace before starting a new one.","Check STATE.trace is None before calling start_trace.","Use STATE.reset_trace() or STATE.reset_client() to clean up stale traces."],"tags":["x64dbg","debugger-agent","state-machine","runtimeerror","trace-lifecycle","duplicate"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}