NationalSecurityAgency/ghidra · error · KeyError
Invalid domain object id: {request.oid.id}
Error message
Invalid domain object id: {request.oid.id} What it means
Raised as KeyError by Client._handle_invoke_method() when an incoming invoke-method request references an oid (domain/trace object id) that is not present in the server's self._traces map. The trace was never created, was already closed/removed, or the id is stale.
Source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/client.py:1352
def _handle(reply: bufs.ReplyDisassemble) -> int:
return reply.length
return self._batch_or_now(root, 'reply_disassemble', _handle)
def _negotiate(self, description: str) -> str:
root = bufs.RootMessage()
root.request_negotiate.version = VERSION
root.request_negotiate.description = description
self._write_methods(root.request_negotiate.methods,
self._method_registry._methods.values())
def _handle(reply: bufs.ReplyNegotiate) -> str:
return reply.description
return self._now(root, 'reply_negotiate', _handle)
def _handle_invoke_method(self, request: bufs.XRequestInvokeMethod) -> Any:
if request.HasField('oid'):
if request.oid.id not in self._traces:
raise KeyError(f"Invalid domain object id: {request.oid.id}")
trace = self._traces[request.oid.id]
else:
trace = None
name = request.name
if not name in self._method_registry._methods:
raise KeyError(f"Invalid method name: {name}")
method = self._method_registry._methods[name]
kwargs = self._read_arguments(request.arguments, trace)
return method.callback(**kwargs)
class Receiver(Thread):
__slots__ = ('client', 'req_queue', '_is_shutdown')
def __init__(self, client: Client) -> None:
super().__init__(daemon=True)
self.client: Client = client
self.req_queue: deque[RemoteResult[Any, Any]] = deque()View on GitHub (pinned to d5f144c24d)
Solutions
- Re-open/refresh the Trace handle on the client before invoking trace-scoped methods after any disconnect or close.
- Discard cached oids when the corresponding Trace is closed.
- Catch KeyError around invoke and re-establish the trace, then retry once.
Example fix
# before
trace.some_method() # oid no longer valid on server
# after
try:
trace.some_method()
except KeyError:
trace = client.open_trace(...)
trace.some_method() Defensive patterns
Strategy: try-catch
Validate before calling
if oid not in client._traces:
raise KeyError(f'oid {oid} not open on server') Try / catch
try:
result = method(...)
except KeyError:
trace = reopen_trace()
result = method(...) Prevention
- Discard cached oids after close/disconnect.
- Re-open traces before invoking trace-scoped methods.
When it happens
Trigger: A client invokes a trace-scoped method after the trace was closed on the server; the client reused a cached oid from a previous connection; the request references an id that was never opened in this session.
Common situations: Long-lived client holding stale trace handles across a server restart; race between close and a queued method call; client/server desync after an error.
Related errors
- Server is already started
- No batch to end
- Method requires trace binding
- Invalid method name: {name}
- Cannot emulate a trace unless it's opened in the tool.
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/3d5de3defc18673e.
Report an issue: GitHub.