#21017·orca

[Bug]: Force Reload silently does nothing when the shutdown checkpoint fails — the beforeunload veto is honored for reloads, but only close/quit surfaces or degrades it

Author: mmarabelCreated Sep 16, 2026Updated Sep 17, 2026
Labelsos:macos

Operating system

macOS

Orca version

1.4.197 · macOS (Darwin 25.5.0, arm64)

Details

Summary. Force Reload sometimes does nothing at all: no reload, no dialog, no toast, nothing in the UI. It stays dead for the rest of the session — retrying Cmd+Shift+R (and View → Force Reload) never works again until the offending state changes or the app is quit and relaunched.

Seen several times in one session, which is what makes it worth filing: a single flaky reload would be hard to attribute, but the failure is permanent for a whole session once it starts.

Root cause (traced in the current code).

The renderer registers a global beforeunload shutdown checkpoint (src/renderer/src/app-shell/use-app-session-persistence.ts). createShutdownCheckpointBeforeUnloadHandler (src/renderer/src/lib/shutdown-checkpoint-guard.ts:52) calls event.preventDefault() whenever the checkpoint throws, and a prevented beforeunload cancels the navigation. That applies to webContents.reloadIgnoringCache() exactly as it does to a window close — the reload simply never happens.

The checkpoint throws when the session snapshot build fails, or when stageBeforeUnloadSync fails (the main-process handler returns ok !== true, so the preload bridge throws Failed to stage renderer state before unload.).

Two things make this invisible on the reload path specifically:

  1. No override. The only will-prevent-unload handler in the app is the window-close path (src/main/window/main-window-close-lifecycle.ts:127); nothing overrides the veto when the navigation is a reload.
  2. No user-facing message. The failure toast added by #16497 (STA-5505) is wired only into the close paths (window-close-request-coordinator.ts, use-terminal-editor-close-foundation.ts). On the reload path the only traces are a main-process console.error('[app] Failed to stage renderer state before unload:', error) (discarded for a Finder-launched app, cf. #20897), the renderer_shutdown_checkpoint_failed crash breadcrumb, and the data-orca-shutdown-checkpoint-failure DOM attribute.

There is also no retry-then-degrade escape hatch here: createShutdownCheckpointPersist only degrades to a durable-session-only stage when isDegradableShutdownInProgress() is true (an intentional restart or a window close) and no open file is dirty. A plain reload is never degradable, so one deterministic checkpoint failure blocks every subsequent reload attempt rather than just the first.

Expected. Force Reload either reloads, or tells the user why it can't (ideally naming the checkpoint failure), like the close/quit paths now do.

Actual. Nothing happens, with no explanation, indefinitely.

Suggested direction: surface the veto on the reload path — reuse showShutdownCheckpointFailureToast(), or show a dialog naming the reason — and/or treat a user-initiated reload as degradable when no open file is dirty. Handling will-prevent-unload for reloads would make the failure impossible to hide.

Siblings (same createShutdownCheckpointGuard veto, other entry points): #15783 (window close, permanently unclosable), #20897 (quit cancelled by a UI-broadcast throw inside the staging call, cause written to discarded stdout), #15352 (fixed for the quit path by 290f192d84 / a82c54ee7e). If a maintainer prefers to track the reload case as another manifestation of #15783 rather than separately, this can be folded there — the guard is the same object.

Note at filing time: main (e7206f62a8) still carries the reload-path hole — shutdown-checkpoint-guard.ts and shutdown-checkpoint-persist.ts are unchanged from the versions described above.