From fec207cc99ad3810968b347742cd736de6c8f05e Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Fri, 15 May 2026 15:35:00 +0200 Subject: [PATCH] fix(frontend): drop in-memory handle before reloading after DB-draft discard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the "Script/flow loaded from latest saved draft" toast's "Reset to deployed" action ran, it: 1. Deleted the DB draft via DraftService.deleteDraft. 2. Called UserDraft.remove (clears localStorage only). 3. Called goto + loadScript / loadFlow. But the handle's in-memory state still held the now-deleted DB draft and its meta (remoteDraftRev pointing at the gone draft's created_at). On the reload, the editor's loadScript/loadFlow saw `localDraft != undefined` and ran the staleness check, which compared `meta.remoteDraftRev = ` against `currentDraftRev = undefined`. Verdict: "version" stale → spurious "A newer version was deployed on the server" modal, even though nothing on the server actually moved. The editor visibly froze behind the modal because the in-memory state wasn't refreshed. Drop the in-memory state with `handle.setDraftAndMeta(undefined, {})` before the reload — same fix already applied to the "Restored from local storage > Reset to deployed" toast action. apps/edit and apps_raw/edit's "discard draft" actions don't call DraftService.deleteDraft (they just swap the in-memory view to the deployed branch), so they don't hit this codepath. --- .../(root)/(logged)/flows/edit/[...path]/+page.svelte | 8 ++++++++ .../(root)/(logged)/scripts/edit/[...path]/+page.svelte | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte index bc1419b66d..b0042e2ebd 100644 --- a/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/flows/edit/[...path]/+page.svelte @@ -244,6 +244,14 @@ path: flow.path }) UserDraft.remove('flow', flowDraftPath) + // UserDraft.remove only clears localStorage. The + // flowHandle's in-memory state still holds the now- + // deleted DB draft + its meta — loadFlow would treat it + // as a local autosave and the staleness check would fire + // a spurious "newer version was deployed" modal because + // remoteDraftRev moved from "defined" to "undefined". + // Drop the in-memory state first. + flowHandle.setDraftAndMeta(undefined, {}) nobackenddraft = true loadFlow() } diff --git a/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte b/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte index d486bce31e..0faec2326c 100644 --- a/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/scripts/edit/[...path]/+page.svelte @@ -235,6 +235,14 @@ path: bakedBaseline.path }) UserDraft.remove('script', draftPath) + // UserDraft.remove only clears localStorage. The + // scriptHandle's in-memory state still holds the now- + // deleted DB draft + its meta — loadScript would treat + // it as a local autosave and the staleness check + // would fire a spurious "newer version was deployed" + // modal because remoteDraftRev moved from "defined" + // to "undefined". Drop the in-memory state first. + scriptHandle.setDraftAndMeta(undefined, {}) goto(`/scripts/edit/${bakedBaseline.path}`) loadScript() }