NationalSecurityAgency/ghidra · error · IllegalArgumentException

All TraceObject parameters must come from the same trace

Error message

All TraceObject parameters must come from the same trace

What it means

Thrown by RemoteMethod.validate() when two or more TraceObject arguments originate from different Trace instances. The method tracks the first TraceObject's trace and rejects any subsequent TraceObject whose getTrace() differs.

Source

Thrown at Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracermi/RemoteMethod.java:178

	default Trace validate(Map<String, Object> arguments) {
		Trace trace = null;
		SchemaContext ctx = PrimitiveTraceObjectSchema.MinimalSchemaContext.INSTANCE;
		for (Map.Entry<String, RemoteParameter> ent : parameters().entrySet()) {
			if (!arguments.containsKey(ent.getKey())) {
				if (ent.getValue().required()) {
					throw new IllegalArgumentException(
						"Missing required parameter '" + ent.getKey() + "'");
				}
				continue; // Should not need to check the default value
			}
			Object arg = arguments.get(ent.getKey());
			if (arg instanceof TraceObject obj) {
				if (trace == null) {
					trace = obj.getTrace();
					ctx = trace.getObjectManager().getRootSchema().getContext();
				}
				else if (trace != obj.getTrace()) {
					throw new IllegalArgumentException(
						"All TraceObject parameters must come from the same trace");
				}
			}
			SchemaName schName = ent.getValue().type();
			TraceObjectSchema sch = ctx.getSchemaOrNull(schName);
			checkType(ent.getKey(), schName, sch, arg);
		}
		for (Map.Entry<String, Object> ent : arguments.entrySet()) {
			if (!parameters().containsKey(ent.getKey())) {
				throw new IllegalArgumentException("Extra argument '" + ent.getKey() + "'");
			}
		}
		return trace;
	}

	/**
	 * Invoke the remote method, getting a future result.
	 * 

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure all TraceObject arguments come from the same trace; re-fetch objects from the current trace.
  2. Before validate(), assert that all TraceObject args share obj.getTrace().
  3. Close/discard references to the old trace after switching to a new one.

Example fix

// before
method.validate(Map.of("a", objFromTrace1, "b", objFromTrace2));

// after
Trace current = requireCurrentTrace();
TraceObject a = current.getObjectManager().getObjectByPath("a");
TraceObject b = current.getObjectManager().getObjectByPath("b");
method.validate(Map.of("a", a, "b", b));
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all TraceObject args share one trace:
Trace expected = null;
for (Object v : arguments.values()) {
    if (v instanceof TraceObject o) {
        if (expected == null) expected = o.getTrace();
        else if (expected != o.getTrace())
            throw new IllegalStateException("Mixed traces in arguments");
    }
}

Type guard

static boolean allObjectsSameTrace(Map<String,Object> args) {
    Trace t = null;
    for (Object v : args.values()) {
        if (v instanceof TraceObject o) {
            if (t == null) t = o.getTrace();
            else if (t != o.getTrace()) return false;
        }
    }
    return true;
}

Try / catch

try {
    method.validate(arguments);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("same trace")) {
        // refresh all objects from the current trace and retry
    } else throw e;
}

Prevention

When it happens

Trigger: Calling validate() with an argument map containing at least two TraceObject values whose getTrace() returns non-equal traces.

Common situations: Mixing objects from an old trace and a newly opened trace; passing a breakpoint object from one trace and a process object from another; stale references after a target restart created a new trace.

Related errors


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