Repository navigation
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/server
Steps to reproduce
- Run the desktop app with T3 Connect linked, so a relay client (cloudflared) is running, and with OpenCode installed.
- Launch the app and quit it within about 30 seconds (⌘Q).
The 30 seconds is only what makes it reliable today: the shared opencode serve process is still alive then, and stopping it takes a fixed second (#33621), which holds up every later shutdown step. Any shutdown step that runs ahead of the relay runtime's finalizer and takes longer than cloudflared's own exit (about 15ms here) opens the same window.
Expected behavior
Once the server starts shutting down, the relay client is stopped and stays stopped, and the backend exits promptly.
Actual behavior
The relay client is restarted in the middle of shutdown, registers with Cloudflare again, and is then killed while it is still connecting. That kill takes about 2.3 seconds. The backend stop took 4.3 to 4.4 seconds, close to the 5 second point where the desktop sends SIGKILL. The Dock icon stays running for that whole time after the window is gone.
What I think is happening, from the logs below and the code on main (bbdc7dc):
- The desktop stops the backend by signalling its process group. The relay client is spawned with
detached: false(apps/server/src/cloud/ManagedEndpointRuntime.ts:746), so it is in that group and gets the SIGTERM directly. It exits cleanly about 15ms later. superviseConnector(same file, line 319) sees the exit. The desired config is still set, so it logs "Relay client exited; restarting" and spawns a replacement.- The desired config is only cleared by the runtime's own finalizer,
runtime.applyConfig(null)(line 915). That runs after the shutdown steps ahead of it, here about one second later.releaseManagedTunnelOnShutdownruns earlier, but it returns beforeapplyConfig(null)for links it does not release. - That finalizer then stops the replacement, which is mid-registration (2 of 4 connections up). The stop has no force-kill bound and waited 2.3 seconds for cloudflared to exit.
On quits where the finalizer ran before the supervisor saw the exit (no OpenCode server alive), there was no restart and the backend stopped in 49ms.
Impact
Minor bug or occasional failure
Version or commit
0.1.8-nightly.20261109.4433. Code references are to main @ bbdc7dc.
Environment
macOS 27.2 arm64, desktop app with its local server, managed relay client 2026.10.4.
Logs or stack traces
Two quits a few seconds after launch. Times are relative to the desktop starting to stop the backend (desktop.backendInstance.closeScope). Relay lines are from relay-client.ndjson, spans from server.trace.ndjson. Tunnel names, IDs and addresses removed.
Quit A (backend stop took 4323ms)
+17ms relay pid 25525: ERR Connection terminated connIndex=2 / 0 / 1 / 3
+17ms relay pid 25525: ERR no more connections active and exiting
+21ms Relay client stopped pid 25525
+22ms Relay client exited; restarting pid 25525, exitCode 0
+23ms Relay client process started; waiting for tunnel connection pid 25840
+335ms relay pid 25840: INF Registered tunnel connection connIndex=0
+525ms relay pid 25840: INF Registered tunnel connection connIndex=1
span OpenCodeServerOwner.closeServer +21ms -> +1024ms (1003ms)
span CloudManagedEndpointRuntime.applyConfig +1032ms -> +3344ms (2312ms)
+3343ms Relay client stopped pid 25840
span AnalyticsService.sendBatch +3369ms -> +4293ms (925ms)
Quit B (backend stop took 4385ms)
+14ms relay pid 26340: ERR no more connections active and exiting
+16ms Relay client exited; restarting pid 26340, exitCode 0
+20ms Relay client process started; waiting for tunnel connection pid 26647
span OpenCodeServerOwner.closeServer +18ms -> +1022ms (1004ms)
span CloudManagedEndpointRuntime.applyConfig +1033ms -> +3351ms (2318ms)
+3350ms Relay client stopped pid 26647
Quit with no OpenCode server alive (backend stop took 49ms)
span CloudManagedEndpointRuntime.applyConfig +15ms -> +17ms (2ms)
+21ms Relay client stopped pid 24299
Workaround
None found. Quitting more than 30 seconds after the last OpenCode use avoids the slow case on this machine.
Notes
- Not checked:
npx t3and the background service. A terminal Ctrl+C also signals the whole foreground group, so I would expect the same restart there, but I have not run it. - Not checked: whether this still happens with perf(opencode): stopping an OpenCode server no longer always waits a full second #33621 applied. That PR removes the fixed second, but the relay finalizer would still run after cloudflared has exited whenever an OpenCode server has to be stopped first, so I expect the restart to remain.
- I did not open a PR because the fix looks like a lifecycle decision rather than a small patch. Options I can see: clear the connector's desired config at the very start of shutdown, make the supervisor aware that the server is stopping, or at least bound how long stopping a connector can take.
Filed by Claude Fable 5.2 in Claude Code on behalf of Ishaan.
Activity
shivamhwp commentedon Nov 10, 2026
Julius has taken this over in #33628, which closes this issue. Stopping this automated job here. No local changes or device tests were started.