windmill-labs/windmill · error
Saving the latest draft failed (${failureMessage ?? 'unknown
Error message
Saving the latest draft failed (${failureMessage ?? 'unknown error'}). Retry before opening a session. What it means
After flushing, flushOrRefuse inspects the syncer's persist state. If state is 'failed', it throws with the syncer's failureMessage, telling the user the latest draft is not durably saved and must be successfully saved before a session can open on it.
Source
Thrown at frontend/src/lib/components/sessions/pageDrawerSession.ts:60
// the user is looking at still holds the edit. The flush is the explicit kind, saving even
// with auto-save off: asking for a session is asking for the edit to come along.
async function flushOrRefuse(query: Parameters<typeof UserDraftDbSyncer.flush>[0]): Promise<void> {
// Before the save, not after: text that does not parse never reached the draft, so
// leaving now would open the session on the last value that did and drop the buffer
// with the drawer — and saving first would write that stale value on the way to
// refusing. The editors were materialised before this call, so the check is current.
if (anyEditorUnparseable()) {
throw new Error('This page has changes that are not valid JSON. Fix them first.')
}
await UserDraftDbSyncer.flush(query)
if (UserDraftDbSyncer.getConflict(query).conflict) {
throw new Error(
'This draft has a newer conflicting version on the server. Resolve it here before opening a session.'
)
}
const { state, failureMessage } = UserDraftDbSyncer.getState(query)
if (state === 'failed') {
throw new Error(
`Saving the latest draft failed (${failureMessage ?? 'unknown error'}). Retry before opening a session.`
)
}
}
// How each page addresses a row in its hash. Resources route theirs through an extra
// segment; every other page names the path directly.
const drawerHashFor = (pagePath: string, itemPath: string) =>
pagePath === RESOURCES_PATH ? `/resource/${itemPath}` : itemPath
/**
* Deep-link the row whose drawer just opened, so the location says what is on screen — a
* drawer opened from a row's Edit button is as open as one reached by link, and the chat
* is told what the session shows through the location alone. No-op off that page, where
* these drawers also open inside editors and pickers with no row convention to keep.
*
* Written straight to history rather than through the router: these pages open their
* drawer *from* the hash, so a router-visible write would come back as a second open onView on GitHub (pinned to e474e8803c)
Solutions
- Retry the save (fix the underlying network/auth issue) until state is success, then open the session
- Check the reported failureMessage for the root cause (401 → re-login, 5xx → server logs)
- Reload the page after connectivity is restored and re-flush
Defensive patterns
Strategy: retry
Validate before calling
const { state } = UserDraftDbSyncer.getState(query)
if (state === 'failed') return; // don't open a session on an unsaved draft Type guard
function isPersisted(state: string): boolean { return state === 'success' } Try / catch
try { await openSession(query) } catch (e) { if (/Saving the latest draft failed/.test(String(e))) scheduleRetryFlush(); else throw e } Prevention
- Check sync state before navigation-gated actions
- Re-authenticate promptly on 401 failures during saves
- Retry flushes after connectivity is restored
When it happens
Trigger: flushOrRefuse(query) where UserDraftDbSyncer.getState(query).state === 'failed' — the flush request to persist the draft errored (network down, 4xx/5xx, auth expired).
Common situations: Working offline or on a flaky connection; API returning 500 during draft save; expired session/token rejecting the draft write.
Related errors
- state.failureMessage ?? `Failed to delete draft "${path}".`
- This page has changes that are not valid JSON. Fix them firs
- This draft has a newer conflicting version on the server. Re
- ApiError with mapped HTTP status message (e.g. "Not Found",
- Generic Error: status: ${errorStatus}; status text: ${errorS
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/9969f7b57f22354d.
Report an issue: GitHub.