-
Notifications
You must be signed in to change notification settings - Fork 27
Description
Project
ide
Description
Plain language
The Prompt Editor modal lets the user close it via the backdrop click or the header X at any time. Those paths do not check whether a Save is in progress (saving is only used to disable the primary Save button). If the user dismisses the modal while updatePrompt / createPrompt is still awaiting storage, the in-flight operation continues and can still write the prompt to disk and update the list. The user reasonably expects “close = discard unsaved work” (or at least “stop what Save was doing”); instead they can get ghost saves or new prompts created after the UI is gone.
This is the same async cancellation / late completion theme as bounty #38008 (API Tokens Cancel vs in-flight Save) but on a different surface (Prompt Library editor), so it is not a duplicate of that ticket—it extends the pattern.
Technical detail
Save path — setSaving(true), then await promptStore.updatePrompt / createPrompt, then closeEditor() in try:
setSaving(true);
try {
const promptData = {
title: title().trim(),
content: content().trim(),
description: description().trim(),
category: category(),
tags: tags(),
isFavorite: isFavorite(),
};
if (isEditing()) {
await promptStore.updatePrompt(promptStore.state.editingPrompt!.id, promptData);
} else {
await promptStore.createPrompt(promptData);
}
promptStore.closeEditor();
} catch (e) {
setErrors([{ field: "general", message: String(e) }]);
} finally {
setSaving(false);
}Dismiss paths — no guard on saving(); always call closeEditor():
const handleClose = () => {
promptStore.closeEditor();
};
return (
<Show when={isOpen()}>
<div
class="fixed inset-0 z-[60] flex items-center justify-center"
style={{ background: "rgba(0,0,0,0.6)" }}
onClick={(e) => {
if (e.target === e.currentTarget) handleClose();
}}Header close uses the same handleClose (lines 214–219 in file). Save is the only control that respects disabled={saving()} (see footer ~510).
PromptStoreContext.updatePrompt / createPrompt both await saveToStorage() — there is no cooperative cancellation.
Error Message
Debug Logs
System Information
OS: Windows 11Screenshots
Steps to Reproduce
- Open Prompt Library and start Create (or Edit an existing prompt).
- Change fields, click Save Changes / Create Prompt (or equivalent).
- Immediately click the backdrop (outside the card) or the X before the save finishes (slow disk or throttle helps).
Expected Behavior
- Dismissing the modal while save is in-flight either aborts the operation, or ignores completion so no partial/undesired persistence occurs; or dismiss is blocked until save completes (with clear UX).
Actual Behavior
Actual
- Modal closes (
closeEditor()), butupdatePrompt/createPromptcan still complete and persist data the user thought they cancelled. For create, a new prompt may appear after dismiss.
Suggested direction (implementation notes)
- While
saving()is true: ignore backdrop/X or show confirm; or use a save generation id /let cancelled = falseon open and check afterawaitbefore applying side effects / secondcloseEditor(). - Align behavior with product decision: “Save is atomic and cannot be cancelled” → disable all dismiss affordances until
finallyruns.
Relation to existing issues
- [bug][alpha] CortexAccountPanel API Tokens: Cancel does not abort in-flight Save #38008 — API Tokens: same class of bug (cancel/dismiss vs in-flight async save). This report is Prompt Editor only; fixing one may inform the other but they are separate UI flows.
Additional Context
No response