{"record":{"id":"e4cf8c335067279f","repo":"NationalSecurityAgency/ghidra","slug":"no-register-mapper-e4cf8c","errorCode":null,"errorMessage":"No register mapper","messagePattern":"No register mapper","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py","lineNumber":94,"sourceCode":"        self.code = code\n\n    def __str__(self) -> str:\n        return repr(self.code)\n\n\nclass Extra(object):\n    def __init__(self) -> None:\n        self.memory_mapper: Optional[arch.DefaultMemoryMapper] = None\n        self.register_mapper: Optional[arch.DefaultRegisterMapper] = None\n\n    def require_mm(self) -> arch.DefaultMemoryMapper:\n        if self.memory_mapper is None:\n            raise RuntimeError(\"No memory mapper\")\n        return self.memory_mapper\n\n    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:","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py#L76-L112","documentation":"Raised as RuntimeError by Extra.require_rm() when STATE.trace.extra.register_mapper is None. The register mapper is assigned in start_trace(); register operations invoked before that (or on an unwired extra) fail here.","triggerScenarios":"Issuing a register read/write before ghidra_trace_start(); a Trace[Extra] whose register_mapper was never populated.","commonSituations":"Register op dispatched before trace start; arch.compute_register_mapper() returned None-equivalent; start_trace() failed after memory_mapper was set.","solutions":["Confirm ghidra_trace_start() completed and set extra.register_mapper.","Guard: if trace.extra.register_mapper is None: report 'start trace first'.","Validate compute_register_mapper() returns a mapper for the detected language."],"exampleFix":"// before\nrm = trace.extra.require_rm()  # RuntimeError\n// after\nif trace.extra.register_mapper is None:\n    raise RuntimeError(\"call ghidra_trace_start before register ops\")\nrm = trace.extra.require_rm()","handlingStrategy":"validation","validationCode":"trace = STATE.require_trace()\nif trace.extra.register_mapper is None:\n    raise RuntimeError('call ghidra_trace_start before register operations')\nrm = trace.extra.require_rm()","typeGuard":"def has_register_mapper(trace) -> bool:\n    return getattr(getattr(trace, 'extra', None), 'register_mapper', None) is not None","tryCatchPattern":"try:\n    rm = trace.extra.require_rm()\nexcept RuntimeError as e:\n    if 'No register mapper' in str(e):\n        ghidra_trace_start(); rm = trace.extra.require_rm()\n    else:\n        raise","preventionTips":["Run ghidra_trace_start() before any register operation.","Verify compute_register_mapper() returns a mapper for the detected language.","Guard register-op entry points with an extra.register_mapper check."],"tags":["drgn","register-mapper","state-machine","precondition"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}