Skip to content

fix(desktop): fix startup crash from revealMode TDZ during storage-root repair - #5302

Open
ksora94 wants to merge 1 commit into
apache:mainfrom
ksora94:fix/reveal-mode-crash
Open

ksora94 wants to merge 1 commit into
apache:mainfrom
ksora94:fix/reveal-mode-crash

Conversation

@ksora94

@ksora94 ksora94 commented Sep 14, 2026

Copy link
Copy Markdown

Summary

Packaged Desktop can crash during startup when a storage-root identity conflict opens the repair dialog.

showDesktopMessageBox closed over const revealMode before that binding was initialized. Storage-root repair runs earlier in boot, so the dialog path hit a temporal dead zone (Cannot access 'revealMode' before initialization) and aborted startup instead of showing the repair UI.

Move revealMode above showDesktopMessageBox so early startup dialogs can use it safely. After this change, the repair dialog opens instead of crashing.

Verification

Reproduced on packaged nightly. Startup failed with this diagnostic report when [storage-root] root-identity conflict triggered the repair dialog:

Maka Desktop diagnostic report
Captured at: 2026-09-14T08:30:30.837Z

Error
Surface: startup
Title: Maka failed to start
Description: Cannot access 'revealMode' before initialization

Details:

ReferenceError: Cannot access 'revealMode' before initialization
    at showDesktopMessageBox (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/runtime-host-boot.js:246:84)
    at async whileAwaitingPerson (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/startup-step.js:93:16)
    at async showMessageBoxWithDiagnostics (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/native-diagnostic-dialog.js:42:24)
    at async confirmDesktopStorageRootRepair (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/runtime-host-boot.js:1884:26)
    at async resolveDesktopStorageRoot (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/storage-root-startup.js:36:11)
    at async startupStep (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/startup-step.js:75:16)
    at async file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/runtime-host-boot.js:270:33

Environment
Maka: 0.2.0-dev.31.20260913
Build: packaged
Channel: nightly
Electron: 43.4.1
Chrome: 150.0.7871.224
Node: 24.18.1
OS: darwin 25.6.0 (arm64)
Locale: zh-CN
Renderer locale: <unknown>
Renderer user agent: <unknown>
Workspace: ~/Library/Application Support/Maka/workspaces/default
Main process uptime: 3s

Recent main-process logs (4)
[2026-09-14T08:30:27.828Z] LOG [startup] app ready
[2026-09-14T08:30:28.590Z] LOG [shell-env] resolved login-shell PATH (22 entries)
[2026-09-14T08:30:28.898Z] LOG [storage-root] root-identity conflict; parking at repair dialog
[2026-09-14T08:30:28.899Z] ERROR [startup] fatal: ReferenceError: Cannot access 'revealMode' before initialization
    at showDesktopMessageBox (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/runtime-host-boot.js:246:84)
    at async whileAwaitingPerson (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/startup-step.js:93:16)
    at async showMessageBoxWithDiagnostics (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/native-diagnostic-dialog.js:42:24)
    at async confirmDesktopStorageRootRepair (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/runtime-host-boot.js:1884:26)
    at async resolveDesktopStorageRoot (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/storage-root-startup.js:36:11)
    at async startupStep (file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/startup-step.js:75:16)
    at async file:///Applications/Maka.app/Contents/Resources/app.asar/dist/main/runtime-host-boot.js:270:33

Recent local Runtime Host process exits (0)
<none captured>

Runtime Host
Diagnostics unavailable: Runtime Host diagnostics were unavailable before the app opened

Root cause

revealMode was declared after the first await that can raise a person-owned dialog. Any const closed over by that dialog helper is still in the TDZ until execution reaches its initializer.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope:

Cursor (Composer): diagnosed the TDZ from the startup diagnostic report and applied the revealMode reorder in apps/desktop/src/main/runtime-host-boot.ts.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actions github-actions Bot added the effort/S Under 100 readable lines label Sep 14, 2026

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technical GO with one non-blocking P3.

The change moves revealMode above the first storage-root await, so the repair-dialog callback can no longer close over an uninitialized const. I verified the production path with the compiled Desktop main process: an isolated Electron launch with a deliberately stale root-identity marker opens the actionable workspace-repair dialog on this head, while the exact parent exits with ReferenceError: Cannot access 'revealMode' before initialization through confirmDesktopStorageRootRepair and showDesktopMessageBox.

I also checked that the initializer depends only on values already available at this point and that no other reveal behavior changes. Validation passed: build:test, full typecheck/lint/format, ASF headers, Desktop 2,481/2,481, focused startup suites 31/31, renderer architecture 112/112, E2E budget 38, changed-file Biome, diff check, and a clean merge with current main (ea990cab7). GitHub currently exposes only the successful label check; there is no hosted test check. Native Windows/macOS startup was not exercised.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

// Declared before showDesktopMessageBox: storage-root repair (and any other
// pre-window dialog) can run while the rest of this module is still awaiting
// startup steps. Closing over a later `const` hits the temporal dead zone.
const revealMode = resolveWindowRevealMode(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Please add a regression that exercises this production ordering. The four related suites (storage-root-startup, startup-step, main-startup-lifetime, and window-reveal-mode) all pass unchanged on the exact parent, while a real Electron launch with a stale root marker still crashes there with Cannot access 'revealMode' before initialization. The current head opens the repair dialog, so the code fix works, but no checked-in test would catch moving this initializer back below the first storage-root await. A source-order assertion in main-startup-lifetime.test.ts, matching the existing ordering checks there, or an Electron startup fixture for a root-identity collision would lock the regression down.

@likun666661 likun666661 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialization reorder directly fixes the TDZ on the early storage-root repair dialog path. All inputs to resolveWindowRevealMode are already available at the new location, and the existing reveal policy is preserved. This is a minimal, appropriate fix. Non-blocking: please add regression coverage for the production startup ordering, as noted in the existing review thread. This review is based on source and call-chain inspection; I did not independently run Electron. Review submitted by an AI assistant at the explicit request of the account owner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/S Under 100 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants