Note
Grok responding on behalf of Julius.
Thanks for the detailed traces. Triage notes from current main (393ff4c):
What the code does on a missed envelope
- The desktop starts the primary backend with
--bootstrap-fd 3(DesktopBackendConfiguration.ts#L589-L606) and hands the JSON envelope to fd 3 as a child-process input stream (DesktopBackendManager.ts#L449-L507). The envelope carriesmode: "desktop",host,t3HomeanddesktopBootstrapSecret(#L562-L581). readBootstrapEnvelopewaits 1000 ms by default (L86) and wraps the read inEffect.timeoutOption(L145). A timeout, an unavailable fd (L81-L82) or a stream that closes before a line (L136-L138) all resolve toOption.none()with no log or error.resolveServerConfigthen defaultsmodeto"web".desktopBootstrapSecret/desktopBootstrapTokenstay undefined (L361-L362), soPairingGrantStorehas nothing to accept the desktop's credential with, and the auth policy becomesloopback-browserwith one-time-token bootstrap only (EnvironmentAuthPolicy.ts#L23-L37). The bind host falls back to127.0.0.1(server.ts#L252), so the failure mode looks fail-closed rather than more exposed.- Web-mode defaults also kick in:
autoBootstrapProjectFromCwdturns on (config.ts#L368-L376) andnoBrowserturns off (L352-L360). The packaged backend's cwd is the home directory (DesktopEnvironment.ts#L220), so a fallback launch may also create a project rooted at~and may try to open a browser (serverRuntimeStartup.ts#L531-L537, #L596-L603). Thewelcome.autobootstrapspan in your trace fits that path. Worth checking for a stray home-directory project after a failed launch.
Why it might miss the window after an update (not verified)
- The 1 s timer only starts once
readBootstrapEnveloperuns, so a slow module load before that point should not count against it on its own. Something has to stall the read after the timer is armed. - On Windows there is no
/procor/dev/fdpath (bootstrap.ts#L233-L241), so the envelope is read viafs.createReadStreamon the pipe fd (L207-L214). Reads on that path go through the libuv threadpool (see the analysis in #14776 for the telemetry fd). On a cold first launch with Defender scanning freshly installed files, threadpool contention or a long synchronous stall, as you describe, could plausibly push the read past 1 s even with the envelope sitting in the pipe. Neither has been reproduced here. - No test covers the timeout-then-web-mode fallback; bootstrap.test.ts only exercises the success, unavailable-fd and error paths.
Desktop side
invalid_credentialis final:isTransientBearerBootstrapErrorretries only fetch/timeout and 502-504 (from #12919), and the failure surfaces asDesktopLocalEnvironmentAuthSessionBootstrapError(L118-L124) through the bearer-token IPC (window.ts#L175-L183). Nothing on that path restarts the backend.- Readiness only checks that
/.well-known/t3/environmentanswers (DesktopBackendManager.ts#L378-L399, #L616-L633); the descriptor it returns does not include the server mode, so a web-mode backend looks ready. The sticky error screen is #3513.
Possible fix directions (for maintainers to choose)
- Fail closed on the server: when
--bootstrap-fd/T3CODE_BOOTSTRAP_FDis set and no envelope arrives, exit nonzero with a clear error instead of starting in web mode, so the desktop supervisor restarts it. Smallest change; it does turn a slow start into a restart loop if the stall repeats. - Wait longer: raise the timeout for an explicit fd (or wait until a line or EOF), possibly with a log line when the envelope is late. On Windows, reading the pipe through
net.Socketinstead offs.createReadStream, as #14776 does for telemetry, may remove the threadpool dependency. - Detect the mismatch on the desktop: check the auth descriptor (expecting
desktop-managed-local) or treatinvalid_credentialfrom the primary local backend as "respawn once" before surfacing the error.
Options 1 or 2 address the root cause; option 3 is a safety net and could pair with either.
Related
- #16826: same
invalid_credentialsymptom, different cause (WSL service on the same port). Not a duplicate. - #3513: sticky error UI with no recovery.
- #12918 / #12919: transient bearer bootstrap retries, which don't cover a rejected credential.
- #14776 (open): same
fs.createReadStream-on-pipe pattern for the telemetry fd. - I didn't find an open or merged PR that changes the envelope timeout or the silent web-mode fallback.