{"record":{"id":"f7bc877bb9ed071e","repo":"NationalSecurityAgency/ghidra","slug":"thread-must-be-given-e-g-0-t1-3-since-the-last","errorCode":null,"errorMessage":"Thread must be given, e.g., 0:t1-3, since the last thread or snapshot event thread is not given.","messagePattern":"Thread must be given, e\\.g\\., 0:t1-3, since the last thread or snapshot event thread is not given\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/Step.java","lineNumber":112,"sourceCode":"\n\tStepType getType();\n\n\tdefault int getTypeOrder() {\n\t\treturn getType().ordinal();\n\t}\n\n\tboolean isNop();\n\n\tlong getThreadKey();\n\n\tdefault boolean isEventThread() {\n\t\treturn getThreadKey() == -1;\n\t}\n\n\tstatic TraceThread requireThread(TraceThread thread, long key) {\n\t\tif (thread == null) {\n\t\t\tif (key == -1) {\n\t\t\t\tthrow new IllegalArgumentException(\"Thread must be given, e.g., 0:t1-3, \" +\n\t\t\t\t\t\"since the last thread or snapshot event thread is not given.\");\n\t\t\t}\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\"Thread with key %d does not exist in given trace\".formatted(key));\n\t\t}\n\t\treturn thread;\n\t}\n\n\tdefault TraceThread getThread(TraceThreadManager tm, TraceThread eventThread) {\n\t\tlong key = getThreadKey();\n\t\treturn requireThread(isEventThread() ? eventThread : tm.getThread(key), key);\n\t}\n\n\tlong getTickCount();\n\n\tlong getSkipCount();\n\n\tlong getPatchCount();","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/Step.java#L94-L130","documentation":"Step.requireThread throws this specific message when the thread resolved to null AND the key is -1 (the sentinel for 'last thread or event thread'). This means the caller asked to operate on the event thread, but no event thread is available in the current context — the trace has no snapshot event thread and no last-thread state to fall back on.","triggerScenarios":"Calling step.getThread(threadManager, null) when the step uses key -1 (event thread) but eventThread is null. This happens when a schedule references the implicit event thread but the trace or snapshot has no associated event thread. Also when operating on a freshly created trace with no threads or events recorded yet.","commonSituations":"Creating a schedule with a default thread reference (no 'tN-' prefix) and applying it to a trace that has no threads or no snapshot event thread. Loading a trace from a target session where the event thread was never set. Using schedules from one trace context on a different trace where thread keys differ.","solutions":["Specify the thread explicitly in the schedule: '0:t1-5' instead of '0:5'","Ensure the trace has an event thread set before using implicit-thread schedules: check trace.getThreadManager().getAllThreads() is non-empty","If building schedules programmatically, use a concrete thread key obtained from the trace rather than -1","Verify the snapshot has an event thread: snapshot.getEventThread() != null before stepping"],"exampleFix":"// before\n// schedule uses implicit event thread: \"snap:5\"\nTraceSchedule.parse(\"0:5\", Source.ABNORMAL, TimeRadix.DEC);\n// after\n// specify thread explicitly: \"snap:t1-5\"\nTraceSchedule.parse(\"0:t1-5\", Source.ABNORMAL, TimeRadix.DEC);","handlingStrategy":"validation","validationCode":"boolean hasEventThread(Trace trace, TraceSnapshot snap) {\n    return snap != null && snap.getEventThread() != null\n        || !trace.getThreadManager().getAllThreads().isEmpty();\n}","typeGuard":"// N/A — runtime context check","tryCatchPattern":"try {\n    TraceThread thread = step.getThread(tm, eventThread);\n} catch (IllegalArgumentException e) {\n    // no event thread available; require explicit thread key in schedule\n}","preventionTips":["Always specify thread keys explicitly in schedules: '0:t1-5' not '0:5'","Ensure the trace has at least one thread and a snapshot event thread before stepping","Validate that eventThread != null before using implicit-thread schedules"],"tags":["ghidra","trace-schedule","thread","precondition"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}