NationalSecurityAgency/ghidra · error · IllegalArgumentException
Thread with key %d does not exist in given trace
Error message
Thread with key %d does not exist in given trace
What it means
Step.requireThread throws this when the resolved thread is null but a specific key (not -1) was requested. This means threadManager.getThread(key) returned null — no thread with that key exists in the trace. The key is a long identifier assigned to each thread when it is created in the trace.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/Step.java:115
default int getTypeOrder() {
return getType().ordinal();
}
boolean isNop();
long getThreadKey();
default boolean isEventThread() {
return getThreadKey() == -1;
}
static TraceThread requireThread(TraceThread thread, long key) {
if (thread == null) {
if (key == -1) {
throw new IllegalArgumentException("Thread must be given, e.g., 0:t1-3, " +
"since the last thread or snapshot event thread is not given.");
}
throw new IllegalArgumentException(
"Thread with key %d does not exist in given trace".formatted(key));
}
return thread;
}
default TraceThread getThread(TraceThreadManager tm, TraceThread eventThread) {
long key = getThreadKey();
return requireThread(isEventThread() ? eventThread : tm.getThread(key), key);
}
long getTickCount();
long getSkipCount();
long getPatchCount();
/**
* Check if the given step can be combined with this oneView on GitHub (pinned to d5f144c24d)
Solutions
- List available threads and their keys: trace.getThreadManager().getAllThreads() and use a valid key
- Re-derive the schedule from the current trace's thread keys
- If the thread was deleted, either recreate it or update the schedule to reference an existing thread
- Validate the key before stepping: trace.getThreadManager().getThread(key) != null
Example fix
// before
// t5 may not exist in this trace
TraceSchedule.parse("0:t5-10", Source.ABNORMAL, TimeRadix.DEC);
// after
// look up an actual thread key
TraceThread t = trace.getThreadManager().getAllThreads().get(0);
String spec = "0:t" + t.getKey() + "-10";
TraceSchedule.parse(spec, Source.ABNORMAL, TimeRadix.DEC); Defensive patterns
Strategy: validation
Validate before calling
boolean threadExists(Trace trace, long key) {
return key == -1 || trace.getThreadManager().getThread(key) != null;
} Type guard
// N/A
Try / catch
try {
TraceThread thread = step.getThread(tm, eventThread);
} catch (IllegalArgumentException e) {
// thread key is stale; list available threads
List<TraceThread> all = tm.getAllThreads();
// re-derive schedule with a valid key
} Prevention
- Never assume thread keys persist across trace sessions
- Validate keys against the current trace's ThreadManager before stepping
- When loading saved schedules, re-map thread keys to the current trace
When it happens
Trigger: Calling step.getThread() where the step references a thread key that does not exist in the trace's ThreadManager. Using a schedule from a different trace session where thread keys were assigned differently. Referencing a thread that was deleted or never created.
Common situations: Reusing a schedule string across trace sessions — thread keys are per-trace and may differ. Deleting a thread from the trace after the schedule was created. Loading a trace that was partially corrupted or is missing thread records. Using stale schedule bookmarks from a previous emulation session.
Related errors
- Thread must be given, e.g., 0:t1-3, since the last thread or
- Cannot rewind a negative number
- The given prefix (%s) is not actually a prefix of this (%s).
- Cannot have instructions steps following p-code steps
- Memory addresses cannot be associated with a thread
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/7cee5588a2255086.
Report an issue: GitHub.