NationalSecurityAgency/ghidra · error · IllegalStateException
Must save breakpoint to program before naming it
Error message
Must save breakpoint to program before naming it
What it means
ProgramBreakpoint stores its extrinsic properties (name, sleigh) inside the comment of a program Bookmark (the enabled or disabled bookmark). setName() calls getBookmark() and refuses to proceed when no bookmark exists, because there is nowhere to persist the name. A ProgramBreakpoint only has a backing bookmark once it has been written/saved into the program (i.e. toggled to an enabled or disabled state that creates the bookmark).
Source
Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/ProgramBreakpoint.java:248
/**
* Get the user-defined name of the breakpoint
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Set the name of the breakpoint
*
* @param name the name
*/
public void setName(String name) {
Bookmark bookmark = getBookmark();
if (bookmark == null) {
throw new IllegalStateException("Must save breakpoint to program before naming it");
}
this.name = name;
writeProperties(bookmark);
}
/**
* Get the sleigh injection for this breakpoint
*
* @return the sleigh injection
*/
public String getEmuSleigh() {
return sleigh;
}
/***
* Set the sleigh injection for this breakpoint
*
* @param sleigh the sleigh injectionView on GitHub (pinned to d5f144c24d)
Solutions
- Persist the breakpoint into the program first (set it to an enabled or disabled mode so getBookmark() returns a bookmark) before calling setName.
- Guard setName with a null check on getBookmark(); if absent, create the bookmark via the breakpoint service or skip naming.
- Use the logical breakpoint service APIs (DebuggerLogicalBreakpointServicePlugin) which create bookmarks and set names in the correct order.
- If the bookmark was deleted, re-create the breakpoint before renaming.
Example fix
// before
ProgramBreakpoint brk = new ProgramBreakpoint(program, addr, 1, kinds);
brk.setName("foo"); // throws: no bookmark yet
// after
ProgramBreakpoint brk = new ProgramBreakpoint(program, addr, 1, kinds);
// write the breakpoint into the program so a bookmark exists first
brk.writeEnabled(...); // or use the breakpoint service to persist it
if (brk.getBookmark() != null) {
brk.setName("foo");
} Defensive patterns
Strategy: validation
Validate before calling
// Run before setName(...)
public static boolean canName(ProgramBreakpoint brk) {
return brk.getBookmark() != null;
}
// usage:
if (canName(brk)) {
brk.setName(name);
} else {
// persist/enable the breakpoint first, then name it
} Type guard
// ProgramBreakpoint is not parameterized; guard on bookmark presence
public static boolean hasBackingBookmark(ProgramBreakpoint brk) {
return brk != null && brk.getBookmark() != null;
} Try / catch
try {
brk.setName(name);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Must save breakpoint")) {
// persist breakpoint (enable/disable) to create bookmark, then retry setName
} else throw e;
} Prevention
- Always persist a ProgramBreakpoint into the program (create its bookmark) before setting extrinsic properties like name/sleigh.
- Prefer the logical breakpoint service which orders bookmark creation and property writes correctly.
- In tests/UI flows, check getBookmark() before exposing rename actions.
When it happens
Trigger: Constructing a ProgramBreakpoint via new ProgramBreakpoint(program, address, length, kinds) and immediately calling setName(...) before ever creating a bookmark. Calling setName on a breakpoint whose bookmark was deleted (absent state). The check is getBookmark() == null -> throw IllegalStateException.
Common situations: Programmatic breakpoint management scripts that build a ProgramBreakpoint and try to label it without first enabling it. UI flows that rename a breakpoint that the user disabled-to-absent. Tests that construct breakpoints directly bypassing the bookmark creation path.
Related errors
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/72fb123adb4812a8.
Report an issue: GitHub.