{"record":{"id":"9de847c22c7fb5df","repo":"NationalSecurityAgency/ghidra","slug":"trace-must-be-opened-before-activated","errorCode":null,"errorMessage":"Trace must be opened before activated: {}","messagePattern":"Trace must be opened before activated: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServicePlugin.java","lineNumber":1164,"sourceCode":"\t\t\t\t\t.sorted(Comparator.comparing(l -> -l.time))\n\t\t\t\t\t.findFirst()\n\t\t\t\t\t.map(l -> l.coords)\n\t\t\t\t\t.orElse(DebuggerCoordinates.NOWHERE);\n\t\t}\n\t}\n\n\t@Override\n\tpublic CompletableFuture<Void> activateAndNotify(DebuggerCoordinates coordinates,\n\t\t\tActivationCause cause) {\n\t\tTrace newTrace = coordinates.getTrace();\n\t\tsynchronized (listenersByTrace) {\n\t\t\tif (newTrace != null && !listenersByTrace.containsKey(newTrace)) {\n\t\t\t\tif (cause == ActivationCause.FOLLOW_PRESENT) {\n\t\t\t\t\tMsg.error(this,\n\t\t\t\t\t\t\"Ignoring activation because FOLLOW_PRESENT for non-opened trace\");\n\t\t\t\t\treturn AsyncUtils.nil();\n\t\t\t\t}\n\t\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Trace must be opened before activated: \" + newTrace);\n\t\t\t}\n\t\t\tif (newTrace == null && ensureActiveTrace) {\n\t\t\t\tcoordinates = getMostRecentCoordinates(); // Might still be NOWHERE\n\t\t\t}\n\t\t}\n\n\t\tif (cause == ActivationCause.FOLLOW_PRESENT || cause == ActivationCause.TARGET_UPDATED) {\n\t\t\tif (!isFollowsPresent(newTrace) && cause == ActivationCause.FOLLOW_PRESENT) {\n\t\t\t\treturn AsyncUtils.nil();\n\t\t\t}\n\t\t\tif (current.getTrace() != newTrace) {\n\t\t\t\t// The snap needs to match upon re-activating this trace.\n\t\t\t\ttry {\n\t\t\t\t\tTraceVariableSnapProgramView view = newTrace.getProgramView();\n\t\t\t\t\tview.setSnap(coordinates.getViewSnap());\n\t\t\t\t\tview.setPlatform(coordinates.getPlatform());\n\t\t\t\t}","sourceCodeStart":1146,"sourceCodeEnd":1182,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServicePlugin.java#L1146-L1182","documentation":"DebuggerTraceManagerServicePlugin.activateAndNotify() requires that any non-null target trace already be registered with the manager (present in listenersByTrace, which is populated by openTrace). Activating a trace that was never opened is a state error: IllegalStateException(\"Trace must be opened before activated: \" + newTrace). Note FOLLOW_PRESENT causes a logged ignore instead of a throw, but all other causes throw.","triggerScenarios":"Calling activateAndNotify (or activate) with coordinates pointing at a Trace that was not opened via openTrace. Activating after the trace was closed. Programmatically building DebuggerCoordinates with a foreign/closed trace.","commonSituations":"Scripts that construct coordinates for a trace loaded but not opened. Re-activating a stale trace reference after the user closed it. Race between close and an activation callback for a non-FOLLOW_PRESENT cause.","solutions":["Open the trace with traceManager.openTrace(trace) (which registers it in listenersByTrace) before activating.","Guard activation by checking the trace is currently open; if not, open it or skip.","For follow-present flows, ensure the cause is FOLLOW_PRESENT so a non-opened trace is ignored rather than throwing."],"exampleFix":"// before\ntraceManager.activateAndNotify(DebuggerCoordinates.NOWHERE.trace(trace), ActivationCause.SOURCE);\n// throws: Trace must be opened before activated\n\n// after\nif (!traceManager.getOpenTraces().contains(trace)) {\n    traceManager.openTrace(trace);\n}\ntraceManager.activateAndNotify(coordinates, ActivationCause.SOURCE);","handlingStrategy":"validation","validationCode":"if (newTrace != null && !traceManager.getOpenTraces().contains(newTrace)) {\n    traceManager.openTrace(newTrace);\n}\ntraceManager.activateAndNotify(coordinates, cause);","typeGuard":"public static boolean isOpenInTool(DebuggerTraceManagerService tm, Trace trace) {\n    return trace == null || tm.getOpenTraces().contains(trace);\n}","tryCatchPattern":"try {\n    traceManager.activateAndNotify(coordinates, cause);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"must be opened before activated\")) {\n        traceManager.openTrace(coordinates.getTrace());\n        traceManager.activateAndNotify(coordinates, cause);\n    } else throw e;\n}","preventionTips":["Always openTrace() before activating; activation requires registration in listenersByTrace.","For follow-present flows use ActivationCause.FOLLOW_PRESENT so non-opened traces are ignored.","Avoid activating stale trace references after close."],"tags":["trace-manager","activation","lifecycle","precondition"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}