NationalSecurityAgency/ghidra · error · IllegalStateException

Tool does not have service {cls}! This script should be run

Error message

Tool does not have service {cls}! This script should be run from the Debugger tool

What it means

Thrown by FlatDebuggerAPI.requireService() when the requested Ghidra tool service is not registered on the current tool. The Flat Debugger API delegates to several debugger services, all of which only exist in the Debugger tool, not in the standard CodeBrowser tool.

Source

Thrown at Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java:118

	 */
	GhidraState getState();

	/**
	 * Require a service from the tool
	 * 
	 * <p>
	 * If the service is missing, an exception is thrown directing the user to run the script from
	 * the Debugger tool.
	 * 
	 * @param <T> the type of the service
	 * @param cls the class of the service
	 * @return the service
	 * @throws IllegalStateException if the service is missing
	 */
	default <T> T requireService(Class<T> cls) {
		T service = getState().getTool().getService(cls);
		if (service == null) {
			throw new IllegalStateException("Tool does not have service " + cls +
				"! This script should be run from the Debugger tool");
		}
		return service;
	}

	/**
	 * Get the trace manager service
	 * 
	 * @return the service
	 */
	default DebuggerTraceManagerService getTraceManager() {
		return requireService(DebuggerTraceManagerService.class);
	}

	/**
	 * Open the given trace in the UI
	 * 
	 * @param trace the trace

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Run the script from the Debugger tool (Tool -> Run Script), not the CodeBrowser tool.
  2. For headless use, configure the tool to include the Debugger tool, or use the Debugger headless analyzer.
  3. Check getState().getTool() name before calling service-requiring methods to fail with a clearer message.

Example fix

// before
// script run from CodeBrowser tool -> throws
DebuggerTraceManagerService tm = getTraceManager();

// after
// Run the script via the Debugger tool (Tools > Debugger), or:
if (!"Debugger".equals(getState().getTool().getName())) {
    println("Run this script from the Debugger tool");
    return;
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify the debugger service is available before use:
Class<?> svc = DebuggerTraceManagerService.class;
if (getState().getTool().getService(svc) == null) {
    throw new IllegalStateException(
        "Run this script from the Debugger tool, not "
            + getState().getTool().getName());
}

Try / catch

try {
    getTraceManager();
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Debugger tool")) {
        println("Please run from the Debugger tool");
    } else throw e;
}

Prevention

When it happens

Trigger: Calling requireService(SomeDebuggerService.class) (or any flat API method like getTraceManager() that calls it) while the script is running under a tool that lacks that service, e.g., the default CodeBrowser tool.

Common situations: Running a FlatDebuggerAPI-based GhidraScript from the CodeBrowser tool instead of the Debugger tool; running in headless mode without the debugger tool configured.

Related errors


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