Skip to content

Closing the CLAUDE.md editor tab silently discards unsaved edits #478

Description

@graysoncooper

What is wrong

Closing the CLAUDE.md editor tab after an unsaved edit discards the edit with no confirmation. The unsaved-changes guard that should intercept the close never runs.

Where

src/components/MarkdownEditor.tsx on the default branch (commit 70c16d8):

*/
export const MarkdownEditor: React.FC<MarkdownEditorProps> = ({
className,
}) => {
const [content, setContent] = useState<string>("");
const [originalContent, setOriginalContent] = useState<string>("");
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [error, setError] = useState<string | null>(null);
const [toast, setToast] = useState<{ message: string; type: "success" | "error" } | null>(null);
const hasChanges = content !== originalContent;
// Load the system prompt on mount
useEffect(() => {
loadSystemPrompt();
}, []);
const loadSystemPrompt = async () => {
try {
setLoading(true);
setError(null);
const prompt = await api.getSystemPrompt();
setContent(prompt);
setOriginalContent(prompt);
} catch (err) {
console.error("Failed to load system prompt:", err);
setError("Failed to load CLAUDE.md file");
} finally {
setLoading(false);
}
};
const handleSave = async () => {
try {
setSaving(true);
setError(null);
setToast(null);
await api.saveSystemPrompt(content);
setOriginalContent(content);
setToast({ message: "CLAUDE.md saved successfully", type: "success" });
} catch (err) {
console.error("Failed to save system prompt:", err);
setError("Failed to save CLAUDE.md file");
setToast({ message: "Failed to save CLAUDE.md", type: "error" });
} finally {
setSaving(false);
}
};

The editor computes hasChanges locally but exposes no callback to lift that dirty state to the tab layer. closeTab in src/hooks/useTabState.ts only prompts when tab.hasUnsavedChanges is true, and markTabAsChanged is exported but never called anywhere, so the CLAUDE.md tab's hasUnsavedChanges stays false.

How it manifests

Open the CLAUDE.md editor tab, edit the content, then close the tab with the X button or the close-tab shortcut. closeTab sees hasUnsavedChanges === false, skips the window.confirm prompt, and removes the tab. The edited content lives only in the editor's local React state and is never persisted, so it is lost. No confirmation appears and no unsaved-changes indicator shows.

Failure scenario

A user edits their CLAUDE.md system prompt, then closes the tab expecting the usual unsaved-changes prompt. The prompt never appears and the edits are gone.

Attribution

This PR migrated the editor into the tab system and removed the earlier handleBack window.confirm('You have unsaved changes...') guard without wiring markTabAsChanged, so the dirty flag is never set for this tab.

Suggested fix

Propagate the editor's hasChanges state to the tab, calling markTabAsChanged when the content diverges from the saved value and clearing it on save, so the existing closeTab confirmation and the unsaved-changes indicator activate for the CLAUDE.md tab.

Automated report: this issue was produced and filed automatically, with no human review before posting. Two independent checks agreed it is a real bug, but if it misreads the code please say so and we will close it.

Found while running Ito (AI code review that runs your application, free for open source) against recently merged PRs. Full analysis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions