Repository navigation
[Bug]: WSL backend goes offline after restart: duplicate desktop-bootstrap exchange revokes the cached session #22951
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/web
Steps to reproduce
- On Windows, enable the WSL backend in Settings > Connections (distro
Ubuntu-24.04, alongside Windows, not WSL-only). - Quit and restart T3 Code.
- Sometimes, within a few seconds of startup, the WSL environment shows "WSL (Ubuntu-24.04) is offline. T3 Code on WSL (Ubuntu-24.04) did not accept this device".
- Click Reconnect. The banner stays.
It's a race, so it doesn't happen on every restart. I saw it on 0.0.42 and again on 0.1.1.
Expected behavior
The renderer makes one desktop-bootstrap exchange per WSL backend at startup. If the bearer is rejected later, the renderer exchanges the bootstrap token again instead of reusing the dead bearer.
Actual behavior
The single renderer window exchanged the same desktop-bootstrap token against the WSL backend twice, 0.7 s apart:
- First:
web.connectionPlatform.loadSecondaryConnectionRegistration→bootstrapRemoteBearerSession→POST <wsl-ip>:3774/oauth/token, under the long-runningEnvironmentRegistry.reconcilePlatformloop. - 0.7 s later: the same call chain under a second
clientRuntime.connection.application.startspan.
Only one window was created (desktop.window.createMain, about 1 s before the first exchange).
On the server, desktop-bootstrap grants use replaceActiveForSubjectAndMethod: true (apps/server/src/auth/EnvironmentAuth.ts:985), so the second exchange revoked the first session. Two seconds later the WSL server starts rejecting the renderer's requests with SessionTokenRevokedError: Session token revoked → ServerAuthInvalidCredentialError. It keeps rejecting them until the backend is toggled.
Reconnect can't recover because apps/web/src/connection/platform.ts reuses the cached bearer as long as the endpoint and bootstrap token are unchanged (canReuseCachedPlatformRegistration). The bootstrap token only rotates every 12 h (packages/shared/src/desktopBootstrapToken.ts), and a revoked or invalid credential doesn't evict the cache entry.
Possible fixes, any one of which would help:
- Make sure only one
buildPlatformRegistrationsruns per renderer at startup, or share one in-flight exchange per backend id. - Evict the cached secondary registration when the server answers with a revoked or invalid session, so the next poll exchanges again.
Impact
Major degradation or frequent failure
Version or commit
0.1.1 (Beta), Windows installer. Same behavior seen on 0.0.42.
Environment
Windows 11, WSL 2 Ubuntu-24.04 (NAT networking)
Logs or stack traces
WSL server trace log, times relative to the first exchange:
+0.0 s POST /oauth/token environment.auth.token Success
+0.7 s POST /oauth/token environment.auth.token Success
+3 s SessionStore.verify SessionTokenRevokedError: Session token revoked.
+3 s EnvironmentAuth.authenticateHttpRequest ServerAuthInvalidCredentialError: Server authentication credential is invalid. (event: Rejected authenticated session credential.)
+45 s (same pair repeats)
+9 min (same pair repeats)
Workaround
Set the WSL backend to Off in Settings > Connections, then back to the distro. Fully restarting the app also works unless it loses the race again.
Activity