NationalSecurityAgency/ghidra · error · IllegalArgumentException

Trace is not from this connection

Error message

Trace is not from this connection

What it means

Thrown by RecordRemoteParameter.getDefaultValue(Trace) when the supplied Trace object is not one of the traces opened by this TraceRmiHandler connection. The handler keeps a registry (openTraces) of traces it created; getOpenTrace(trace) returns null for any trace opened on a different handler, so the parameter's default value cannot be computed in that trace's context.

Source

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

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ghidra.app.plugin.core.debug.service.tracermi;

import ghidra.debug.api.tracermi.RemoteParameter;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.trace.model.Trace;
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;

public record RecordRemoteParameter(TraceRmiHandler handler, String name, SchemaName type,
		boolean required, ValueSupplier defaultValue, String display, String description)
		implements RemoteParameter {

	public Object getDefaultValue(Trace trace) {
		OpenTrace open = handler.getOpenTrace(trace);
		if (open == null) {
			throw new IllegalArgumentException("Trace is not from this connection");
		}
		try {
			return defaultValue().get(open);
		}
		catch (AddressOverflowException e) {
			throw new AssertionError(e);
		}
	}

	@Override
	public Object getDefaultValue() {
		try {
			return defaultValue().get(ValueDecoder.DEFAULT);
		}
		catch (AddressOverflowException e) {
			throw new AssertionError(e);
		}
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Pass a Trace that was created/opened through the same TraceRmiHandler (via createTrace/openTrace) whose RemoteMethod/RemoteParameter you are querying.
  2. If you hold multiple connections, look up the correct handler for the trace before calling getDefaultValue, or use the no-arg getDefaultValue() which does not need a trace.
  3. When a connection is disposed, discard all Trace references obtained from it; do not feed them into another handler's parameters.

Example fix

// before
Object def = param.getDefaultValue(traceFromOtherConnection);

// after
if (handler.getOpenTrace(trace) == null) {
    // use the trace-less default, or re-open via this handler
    Object def = param.getDefaultValue();
} else {
    Object def = param.getDefaultValue(trace);
}
Defensive patterns

Strategy: validation

Validate before calling

OpenTrace open = handler.getOpenTrace(trace);
if (open == null) {
    Object def = param.getDefaultValue(); // trace-less default
} else {
    Object def = param.getDefaultValue(trace);
}

Try / catch

try {
    return param.getDefaultValue(trace);
} catch (IllegalArgumentException e) {
    // trace not from this connection; fall back to trace-less default
    return param.getDefaultValue();
}

Prevention

When it happens

Trigger: Calling RemoteParameter.getDefaultValue(someTrace) where someTrace was created by a different TraceRmi connection, or by Ghidra directly rather than via the TraceRmi handler. Also occurs when passing a Trace from one connection into a method/parameter object that belongs to another.

Common situations: Reusing a Trace object across two debugger sessions/connections; mixing traces opened manually (DBTrace) with those opened via TraceRmi; stale Trace reference held after the connection that created it was disposed.

Related errors


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