{"record":{"id":"8f33d34b7ba89b04","repo":"NationalSecurityAgency/ghidra","slug":"already-connected-8f33d3","errorCode":null,"errorMessage":"Already connected","messagePattern":"Already connected","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py","lineNumber":110,"sourceCode":"    def require_rm(self) -> arch.DefaultRegisterMapper:\n        if self.register_mapper is None:\n            raise RuntimeError(\"No register mapper\")\n        return self.register_mapper\n\n\nclass State(object):\n\n    def __init__(self) -> None:\n        self.reset_client()\n\n    def require_client(self) -> Client:\n        if self.client is None:\n            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()","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py#L92-L128","documentation":"Raised as RuntimeError by State.require_no_client() when STATE.client is already set. Commands that establish a connection (ghidra_trace_connect/listen) refuse to run twice to avoid leaking sockets; you must disconnect first.","triggerScenarios":"Calling ghidra_trace_connect() or ghidra_trace_listen() while a previous connection is still active.","commonSituations":"Re-running a connect script without an intervening ghidra_trace_disconnect(); a connect that partially succeeded and left client set.","solutions":["Call ghidra_trace_disconnect() before re-connecting.","Guard: if STATE.client is not None: disconnect first.","In startup scripts, make connect idempotent by checking require_no_client only when client is None."],"exampleFix":"// before\nghidra_trace_connect(address)  # RuntimeError: Already connected\n// after\nif STATE.client is not None:\n    ghidra_trace_disconnect()\nghidra_trace_connect(address)","handlingStrategy":"validation","validationCode":"if STATE.client is not None:\n    raise RuntimeError('already connected; call ghidra_trace_disconnect first')\n# or just disconnect:\nif STATE.client is not None:\n    ghidra_trace_disconnect()","typeGuard":"def is_disconnected() -> bool:\n    return getattr(STATE, 'client', None) is None","tryCatchPattern":"try:\n    ghidra_trace_connect(address)\nexcept RuntimeError as e:\n    if 'Already connected' in str(e):\n        ghidra_trace_disconnect(); ghidra_trace_connect(address)\n    else:\n        raise","preventionTips":["Call ghidra_trace_disconnect() before re-connecting.","Make connect scripts idempotent: disconnect-if-connected, then connect.","Avoid running connect twice from nested scripts."],"tags":["drgn","connection","state-machine","precondition"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}