NationalSecurityAgency/ghidra · error · IllegalStateException

Address requires a trace for context

Error message

Address requires a trace for context

What it means

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.

Source

Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/ValueDecoder.java:79

				case ID -> "<Object id=%d>".formatted(spec.getId());
				case PATH -> "<Object path=%s>".formatted(spec.getPath());
				default -> "<ERROR: default>";
			};
		}

		@Override
		public Object toValue(Value value) {
			Object obj = ValueDecoder.super.toValue(value);
			if (obj instanceof byte[] va) {
				return NumericUtilities.convertBytesToString(va, ":");
			}
			return obj;
		}
	};

	default Address toAddress(Addr addr, boolean required) {
		if (required) {
			throw new IllegalStateException("Address requires a trace for context");
		}
		return null;
	}

	default AddressRange toRange(AddrRange range, boolean required) {
		if (required) {
			throw new IllegalStateException("AddressRange requires a trace for context");
		}
		return null;
	}

	default Object getObject(ObjSpec spec, boolean required) {
		if (required) {
			throw new IllegalStateException("TraceObject requires a trace for context");
		}
		return null;
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Use the OpenTrace instance as the ValueDecoder when you need to resolve addresses, so toAddress has trace context.
  2. If address resolution is optional, call toAddress(addr, false) so a missing context returns null instead of throwing.
  3. Avoid using ValueDecoder.DEFAULT for decoding that involves addresses/ranges/objects.

Example fix

// before
ValueDecoder dec = ValueDecoder.DEFAULT;
Address a = dec.toAddress(addr, true);

// after
ValueDecoder dec = openTrace; // OpenTrace implements ValueDecoder with context
Address a = dec.toAddress(addr, true);
Defensive patterns

Strategy: validation

Validate before calling

ValueDecoder dec = (openTrace != null) ? openTrace : ValueDecoder.DEFAULT;
Address a = (openTrace != null) ? dec.toAddress(addr, true) : null;

Type guard

boolean hasTraceContext(ValueDecoder dec) {
    return dec instanceof OpenTrace;
}

Try / catch

try {
    return dec.toAddress(addr, true);
} catch (IllegalStateException e) {
    return null; // no trace context; address unresolvable
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/66425b25796bd9b3. Report an issue: GitHub.