NationalSecurityAgency/ghidra · error · IllegalArgumentException

Unable to find program: " + programPath

Error message

Unable to find program: " + programPath

What it means

Thrown as IllegalArgumentException from the LocationMemento(SaveState, Program[]) constructor when getProgram(programs, programPath, programID) cannot locate a program matching the saved path/ID in the supplied array. LocationMemento is a saved UI navigation state; restoring it requires the exact program it was captured against to be present and open.

Source

Thrown at Ghidra/Features/Base/src/main/java/ghidra/app/nav/LocationMemento.java:47

public class LocationMemento {
	private static final String PROGRAM_PATH = "PROGRAM_PATH_";
	private static final String PROGRAM_ID = "PROGRAM_ID";
	private static final String MEMENTO_CLASS = "MEMENTO_CLASS";

	protected final ProgramLocation programLocation;
	private final Program program;

	public LocationMemento(Program program, ProgramLocation location) {
		this.program = program;
		this.programLocation = location;
	}

	public LocationMemento(SaveState saveState, Program[] programs) {
		String programPath = saveState.getString(PROGRAM_PATH, null);
		long programID = saveState.getLong(PROGRAM_ID, -1);
		program = getProgram(programs, programPath, programID);
		if (program == null) {
			throw new IllegalArgumentException("Unable to find program: " + programPath);
		}

		programLocation = ProgramLocation.getLocation(program, saveState);
		if (programLocation == null) {
			throw new IllegalArgumentException("Unable to create a program location!");
		}
	}

	public boolean isValid() {
		return program != null && programLocation != null;
	}

	private Program getProgram(Program[] programs, String pathName, long programID) {
		for (Program potentialProgram : programs) {
			if (potentialProgram.getUniqueProgramID() == programID) {
				return potentialProgram;
			}
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure the referenced program is open in the tool and passed in the programs array before restoring the memento.
  2. If the program was moved/renamed, update the saved state's PROGRAM_PATH or re-resolve by content.
  3. Guard isValid() / null-check before constructing, and skip stale mementos gracefully.
  4. Catch IllegalArgumentException and drop the navigation entry rather than crashing the restore.

Example fix

// before
LocationMemento m = new LocationMemento(saveState, programs); // throws if program absent

// after — verify membership first
String path = saveState.getString(LocationMemento.PROGRAM_PATH, null);
boolean present = Arrays.stream(programs).anyMatch(p -> p.getDomainFile().getPathname().equals(path));
if (!present) {
    return null; // skip stale navigation entry
}
LocationMemento m = new LocationMemento(saveState, programs);
Defensive patterns

Strategy: validation

Validate before calling

String path = saveState.getString(LocationMemento.PROGRAM_PATH, null);
boolean present = Arrays.stream(programs)
    .anyMatch(p -> p.getDomainFile().getPathname().equals(path));
if (!present) return null; // skip stale memento

Type guard

boolean restorable = Arrays.stream(programs).anyMatch(p -> p.getDomainFile().getPathname().equals(path));

Try / catch

try {
    m = new LocationMemento(saveState, programs);
} catch (IllegalArgumentException e) {
    // drop stale navigation entry
}

Prevention

When it happens

Trigger: Restoring a LocationMemento (e.g. from a saved tool state or navigation history) where the program at programPath / programID is not among the provided programs array — program not open, renamed, moved, or from a different project.

Common situations: Reopening a Ghidra tool whose saved state references a program no longer in the project; restoring navigation across a project migration where program IDs changed; passing a subset of open programs that omits the referenced one.

Related errors


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