{"record":{"id":"ca5971019dd2863f","repo":"NationalSecurityAgency/ghidra","slug":"breakpoint-must-be-saved-to-a-program-before-namin","errorCode":null,"errorMessage":"Breakpoint must be saved to a program before naming","messagePattern":"Breakpoint must be saved to a program before naming","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LoneLogicalBreakpoint.java","lineNumber":90,"sourceCode":"\n\t@Override\n\tpublic Bookmark getProgramBookmark() {\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic List<Bookmark> getProgramBookmarksValidOrNot() {\n\t\treturn List.of();\n\t}\n\n\t@Override\n\tpublic String getName() {\n\t\treturn \"\";\n\t}\n\n\t@Override\n\tpublic void setName(String name) {\n\t\tthrow new IllegalStateException(\"Breakpoint must be saved to a program before naming\");\n\t}\n\n\t@Override\n\tpublic String getEmuSleigh() {\n\t\treturn breaks.computeSleigh();\n\t}\n\n\t@Override\n\tpublic void setEmuSleigh(String sleigh) {\n\t\tbreaks.setEmuSleigh(sleigh);\n\t}\n\n\t@Override\n\tpublic void setTraceAddress(Trace trace, Address address) {\n\t\tthrow new AssertionError();\n\t}\n\n\t@Override","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/breakpoint/LoneLogicalBreakpoint.java#L72-L108","documentation":"Thrown by LoneLogicalBreakpoint.setName because a 'lone' logical breakpoint has no backing program bookmark (it is not yet persisted/saved). Naming requires a saved breakpoint so the name can be stored on the program bookmark.","triggerScenarios":"Calling setName(name) on a LogicalBreakpoint instance that is a LoneLogicalBreakpoint (created without a program-scoped bookmark, e.g., a trace-only/emulated breakpoint).","commonSituations":"Attempting to rename an emulated or trace-only breakpoint that was never saved to a Program; operating on a breakpoint whose program was closed or never assigned.","solutions":["Save/persist the breakpoint to a program before renaming it.","Check getProgramBookmarksValidOrNot().isEmpty() / whether the breakpoint is a LoneLogicalBreakpoint before calling setName.","Use the trace/object API to set a display name for trace-only breakpoints instead of setName.","Recreate the breakpoint via the normal breakpoint service so it is program-backed."],"exampleFix":"// before\nlogicalBreakpoint.setName(\"mybp\"); // throws if lone/unsaved\n\n// after\nif (logicalBreakpoint.getProgramBookmarksValidOrNot().isEmpty()) {\n    Msg.warn(this, \"Breakpoint not saved to a program; cannot name it\");\n} else {\n    logicalBreakpoint.setName(\"mybp\");\n}","handlingStrategy":"validation","validationCode":"boolean nameable = !logicalBreakpoint.getProgramBookmarksValidOrNot().isEmpty();","typeGuard":"static boolean isSaved(LogicalBreakpoint bp) {\n    return !bp.getProgramBookmarksValidOrNot().isEmpty();\n}","tryCatchPattern":"try {\n    bp.setName(name);\n} catch (IllegalStateException e) {\n    Msg.showWarn(this, null, \"Not saved\", e.getMessage());\n}","preventionTips":["Persist breakpoints to a program before exposing rename.","Distinguish lone vs program-backed breakpoints in the UI."],"tags":["breakpoint","naming","unsaved","program","lone"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}