{"record":{"id":"a98ccac5e93ff2e5","repo":"NationalSecurityAgency/ghidra","slug":"must-set-id-or-path","errorCode":null,"errorMessage":"Must set id or path","messagePattern":"Must set id or path","errorType":"exception","errorClass":"TraceRmiError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/OpenTrace.java","lineNumber":121,"sourceCode":"\n\tpublic TraceObject getObject(ObjPath path, boolean required) {\n\t\tTraceObject object =\n\t\t\ttrace.getObjectManager().getObjectByCanonicalPath(TraceRmiHandler.toKeyPath(path));\n\t\tif (required && object == null) {\n\t\t\tthrow new InvalidObjPathError(path.getPath());\n\t\t}\n\t\treturn object;\n\t}\n\n\t@Override\n\tpublic TraceObject getObject(ObjDesc desc, boolean required) {\n\t\treturn getObject(desc.getId(), required);\n\t}\n\n\t@Override\n\tpublic TraceObject getObject(ObjSpec object, boolean required) {\n\t\treturn switch (object.getKeyCase()) {\n\t\t\tcase KEY_NOT_SET -> throw new TraceRmiError(\"Must set id or path\");\n\t\t\tcase ID -> getObject(object.getId(), required);\n\t\t\tcase PATH -> getObject(object.getPath(), required);\n\t\t\tdefault -> throw new AssertionError();\n\t\t};\n\t}\n\n\tpublic AddressSpace getSpace(String name, boolean required) {\n\t\tAddressSpace space = trace.getBaseAddressFactory().getAddressSpace(name);\n\t\tif (required && space == null) {\n\t\t\tthrow new NoSuchAddressSpaceError(name);\n\t\t}\n\t\treturn space;\n\t}\n\n\t@Override\n\tpublic Address toAddress(Addr addr, boolean required) {\n\t\t/**\n\t\t * Do not clamp here, like we do for ranges. The purpose of the given address is more","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/OpenTrace.java#L103-L139","documentation":"Thrown as TraceRmiError by OpenTrace.getObject(ObjSpec, boolean) when the protobuf ObjSpec message has KEY_NOT_SET — neither the id field nor the path field was populated by the remote client. Every object reference in the Trace RMI protocol must identify its target by id or by path; an empty spec is a client-side protocol violation.","triggerScenarios":"A remote Trace RMI client (a debugger agent/connector) sends a command carrying an ObjSpec but neglects to set either ObjSpec.id or ObjSpec.path before transmitting. The server-side OpenTrace switch hits the KEY_NOT_SET case and rejects it.","commonSituations":"A bug in the connector/agent that constructs object references; a protocol version mismatch where the client expects a field the server reads differently; an automation script building raw ObjSpec messages incorrectly; deserialization of a malformed message leaving both fields unset.","solutions":["On the client/connector side, ensure every ObjSpec sets either .id or .path before sending.","Upgrade the connector/agent to a version compatible with the Ghidra Trace RMI schema.","If scripting, validate that the ObjSpec has one of the two keys set before issuing the command."],"exampleFix":"// before (client side)\nObjSpec spec = ObjSpec.newBuilder().build(); // neither set -> server throws\n\n// after\nObjSpec spec = ObjSpec.newBuilder().setId(123).build();","handlingStrategy":"validation","validationCode":"// Client-side: ensure ObjSpec has id or path set before sending\nObjSpec spec = ...;\nif (spec.getKeyCase() == ObjSpec.KeyCase.KEY_NOT_SET) {\n    throw new IllegalArgumentException(\"ObjSpec must set id or path\");\n}","typeGuard":"boolean isObjSpecValid(ObjSpec s) {\n    return s.getKeyCase() == ObjSpec.KeyCase.ID || s.getKeyCase() == ObjSpec.KeyCase.PATH;\n}","tryCatchPattern":null,"preventionTips":["Always populate either id or path on every ObjSpec before transmitting.","Keep connector/agent versions aligned with the Trace RMI schema.","When scripting raw messages, assert the key case is set."],"tags":["protocol","object-reference","validation","tracermi","ghidra-debug"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}