{"record":{"id":"66425b25796bd9b3","repo":"NationalSecurityAgency/ghidra","slug":"address-requires-a-trace-for-context","errorCode":null,"errorMessage":"Address requires a trace for context","messagePattern":"Address requires a trace for context","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/ValueDecoder.java","lineNumber":79,"sourceCode":"\t\t\t\tcase ID -> \"<Object id=%d>\".formatted(spec.getId());\n\t\t\t\tcase PATH -> \"<Object path=%s>\".formatted(spec.getPath());\n\t\t\t\tdefault -> \"<ERROR: default>\";\n\t\t\t};\n\t\t}\n\n\t\t@Override\n\t\tpublic Object toValue(Value value) {\n\t\t\tObject obj = ValueDecoder.super.toValue(value);\n\t\t\tif (obj instanceof byte[] va) {\n\t\t\t\treturn NumericUtilities.convertBytesToString(va, \":\");\n\t\t\t}\n\t\t\treturn obj;\n\t\t}\n\t};\n\n\tdefault Address toAddress(Addr addr, boolean required) {\n\t\tif (required) {\n\t\t\tthrow new IllegalStateException(\"Address requires a trace for context\");\n\t\t}\n\t\treturn null;\n\t}\n\n\tdefault AddressRange toRange(AddrRange range, boolean required) {\n\t\tif (required) {\n\t\t\tthrow new IllegalStateException(\"AddressRange requires a trace for context\");\n\t\t}\n\t\treturn null;\n\t}\n\n\tdefault Object getObject(ObjSpec spec, boolean required) {\n\t\tif (required) {\n\t\t\tthrow new IllegalStateException(\"TraceObject requires a trace for context\");\n\t\t}\n\t\treturn null;\n\t}\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/ValueDecoder.java#L61-L97","documentation":"Thrown by the default ValueDecoder.toAddress when required is true. The default decoder (ValueDecoder.DEFAULT) has no Trace context, so it cannot resolve an Addr's address-space name into a real AddressSpace. Resolving an address requires an OpenTrace (which has the trace's language and address spaces); only the OpenTrace-backed decoder can do it.","triggerScenarios":"Calling toAddress(addr, true) on ValueDecoder.DEFAULT (or any decoder not bound to a trace) — e.g. decoding a Value that is an Addr in a context where no OpenTrace is available.","commonSituations":"Decoding parameter default values without a trace (RecordRemoteParameter.getDefaultValue() no-arg path uses DEFAULT, which would not reach here for addresses); generic message decoding without a bound trace.","solutions":["Use the OpenTrace instance as the ValueDecoder when you need to resolve addresses, so toAddress has trace context.","If address resolution is optional, call toAddress(addr, false) so a missing context returns null instead of throwing.","Avoid using ValueDecoder.DEFAULT for decoding that involves addresses/ranges/objects."],"exampleFix":"// before\nValueDecoder dec = ValueDecoder.DEFAULT;\nAddress a = dec.toAddress(addr, true);\n\n// after\nValueDecoder dec = openTrace; // OpenTrace implements ValueDecoder with context\nAddress a = dec.toAddress(addr, true);","handlingStrategy":"validation","validationCode":"ValueDecoder dec = (openTrace != null) ? openTrace : ValueDecoder.DEFAULT;\nAddress a = (openTrace != null) ? dec.toAddress(addr, true) : null;","typeGuard":"boolean hasTraceContext(ValueDecoder dec) {\n    return dec instanceof OpenTrace;\n}","tryCatchPattern":"try {\n    return dec.toAddress(addr, true);\n} catch (IllegalStateException e) {\n    return null; // no trace context; address unresolvable\n}","preventionTips":["Use the OpenTrace decoder whenever resolving addresses.","Pass required=false when an address is optional.","Avoid ValueDecoder.DEFAULT for address-bearing values."],"tags":["value-decoder","address","trace-context","trace-rmi"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}