You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: V2 desktop exits on every Windows launch: DesktopClerkBridgeInitializationError (registerSchemesAsPrivileged after ready), since #12480 #13195
A packaged Windows x64 build of the Orchestrator V2 branch (#2829) exits with code 1 on every launch, before any window appears. It fails the same way on two machines (Windows 11 26200 and Windows 10 19045), on a fresh profile and on relaunch. The main process logs one error and quits:
ERROR (#4): DesktopClerkBridgeInitializationError: Failed to initialize the desktop Clerk bridge for state directory "C:\Users\<user>\.t3\userdata" (development: false).
[cause]: Error: protocol.registerSchemesAsPrivileged should be called before app is ready
at createClerkBridge (...\resources\app.asar\apps\desktop\dist-electron\main.cjs:118914:22)
at createDesktopClerkBridge (...\main.cjs:128379:9)
The same commit built for macOS launches normally.
Diagnosis
This is a Windows-only ordering race in desktop startup, and #12480 introduced it.
createClerkBridge (@clerk/electron) calls protocol.registerSchemesAsPrivileged, which must run before Electron's ready. main.ts:220 already notes the risk: "Acquire strict pre-ready setup before Clerk, whose userData resolution can yield and let Electron emit ready."
DesktopClerk.make (apps/desktop/src/app/DesktopClerk.ts:92) first awaits DesktopUserData.resolveUserDataPath(environment) and only then creates the bridge.
On non-win32, resolveUserDataPath returns at DesktopUserData.ts:60 (if (input.platform !== "win32") return destinationPath;) without touching the disk, so it never yields and macOS/Linux are unaffected.
On win32 it goes on to inspect() (DesktopUserData.ts:48) the profile Local State files through the Effect Node FileSystem. fs.exists is async, so the fiber yields to the event loop at least once, and Electron emits ready during that yield. When createClerkBridge then runs, registerSchemesAsPrivileged throws, and DesktopClerkBridgeInitializationError ends startup.
Every Windows launch takes that path, because the first inspect happens regardless of profile state. In our runs it failed deterministically (2 of 2 machines, every launch). Verified against the current #2829 head 060756de5a: DesktopUserData.ts, DesktopClerk.ts and main.ts are unchanged there.
Install release\T3-Code-0.0.42-x64.exe (/S works) and launch T3 Code (Alpha).exe. The process exits within about a second, and running it with --enable-logging=stderr prints the error above.
Windows 11 Pro 26200 x64 and Windows 10 19045 x64; Electron 44.4.2; unsigned packaged NSIS build (dist:desktop:win:x64); Node 26.4, pnpm 11.10.0
Evidence
- Fresh `%USERPROFILE%\.t3\userdata` with only `desktop-settings.json`. There is no `server.trace.ndjson` because the backend never starts. Scheduled-task launches returned `LastTaskResult 1`.
- The single stdout line from the main process is the stack above (fiber #4, the first evaluation). This is not the double-evaluation path from #11720.
- With only the fix below applied, both machines launch normally, the backend binds :3773, and `/.well-known/t3/environment` returns 200 (serverVersion 0.0.42, orchestrationProtocolVersion 2). The rest of the app is unchanged.
Related issues
#12480 (introduced the win32 userData migration), #11720 (same error string, different cause: double evaluation of main.cjs on Linux)
Fix applied or workaround
Local fix (fork): in DesktopClerk.make, run resolveUserDataPath against a synchronous FileSystem, so userData resolution can no longer yield before the bridge exists. The resolver and its tests stay untouched:
preReadySyncFileSystem is FileSystem.makeNoop({ exists, readFileString, makeDirectory, writeFileString }), implemented with node:fsexistsSync/readFileSync/mkdirSync/writeFileSync (errno mapped to PlatformError.systemError, so the wx/AlreadyExists path still works). tsc is clean and the desktop src/app tests pass (76/76). Commit: astarktc@ea60f40f7a
An alternative that avoids sync I/O is to create the bridge before resolving userData. That only works if the bridge's single-instance lock doesn't depend on app.setPath("userData"), which the current comment says it does.
Filed by
Pi (claude-opus-5-5) in a T3 Code thread, operator-reviewed
What happened
A packaged Windows x64 build of the Orchestrator V2 branch (#2829) exits with code 1 on every launch, before any window appears. It fails the same way on two machines (Windows 11 26200 and Windows 10 19045), on a fresh profile and on relaunch. The main process logs one error and quits:
The same commit built for macOS launches normally.
Diagnosis
This is a Windows-only ordering race in desktop startup, and #12480 introduced it.
createClerkBridge(@clerk/electron) callsprotocol.registerSchemesAsPrivileged, which must run before Electron'sready.main.ts:220already notes the risk: "Acquire strict pre-ready setup before Clerk, whose userData resolution can yield and let Electron emit ready."DesktopClerk.make(apps/desktop/src/app/DesktopClerk.ts:92) first awaitsDesktopUserData.resolveUserDataPath(environment)and only then creates the bridge.resolveUserDataPathreturns atDesktopUserData.ts:60(if (input.platform !== "win32") return destinationPath;) without touching the disk, so it never yields and macOS/Linux are unaffected.inspect()(DesktopUserData.ts:48) the profileLocal Statefiles through the Effect NodeFileSystem.fs.existsis async, so the fiber yields to the event loop at least once, and Electron emitsreadyduring that yield. WhencreateClerkBridgethen runs,registerSchemesAsPrivilegedthrows, andDesktopClerkBridgeInitializationErrorends startup.Every Windows launch takes that path, because the first
inspecthappens regardless of profile state. In our runs it failed deterministically (2 of 2 machines, every launch). Verified against the current #2829 head060756de5a:DesktopUserData.ts,DesktopClerk.tsandmain.tsare unchanged there.Steps to reproduce
060756de5a, also reproduced at2341c5a680).pnpm install&&pnpm dist:desktop:win:x64.release\T3-Code-0.0.42-x64.exe(/Sworks) and launchT3 Code (Alpha).exe. The process exits within about a second, and running it with--enable-logging=stderrprints the error above.Version
0.0.42 (Orchestrator V2 branch #2829, head 060756d; also 2341c5a)
Environment
Windows 11 Pro 26200 x64 and Windows 10 19045 x64; Electron 44.4.2; unsigned packaged NSIS build (dist:desktop:win:x64); Node 26.4, pnpm 11.10.0
Evidence
Related issues
#12480 (introduced the win32 userData migration), #11720 (same error string, different cause: double evaluation of main.cjs on Linux)
Fix applied or workaround
Local fix (fork): in
DesktopClerk.make, runresolveUserDataPathagainst a synchronousFileSystem, so userData resolution can no longer yield before the bridge exists. The resolver and its tests stay untouched:preReadySyncFileSystemisFileSystem.makeNoop({ exists, readFileString, makeDirectory, writeFileString }), implemented withnode:fsexistsSync/readFileSync/mkdirSync/writeFileSync(errno mapped toPlatformError.systemError, so thewx/AlreadyExistspath still works). tsc is clean and the desktopsrc/apptests pass (76/76). Commit: astarktc@ea60f40f7aAn alternative that avoids sync I/O is to create the bridge before resolving userData. That only works if the bridge's single-instance lock doesn't depend on
app.setPath("userData"), which the current comment says it does.Filed by
Pi (claude-opus-5-5) in a T3 Code thread, operator-reviewed