Skip to content

[Bug]: Desktop backend outlives a crashed main process and keeps its port, so the relaunch silently moves to another port #13747

Description

@marcuscastelo

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. On Linux, run the desktop app with its backend on the default port 3773 and pair another machine to http://<host>:3773 as a saved environment.
  2. Make the desktop main process crash. [Bug]: Desktop main process SIGTRAPs when dragging a file with non-ASCII characters and a space in its name into the composer (Linux/Wayland) #13746 is a deterministic way to trigger this, but any abnormal exit works (for example kill -TRAP <main pid>).
  3. Relaunch the desktop app.

Expected behavior

The embedded backend exits together with the main process, and the relaunched app gets 3773 again.

Actual behavior

The backend child (t3code --require …/resources/app.asar/…) survives the crash. It is reparented to systemd --user and keeps listening on 0.0.0.0:3773. The relaunched app scans past the busy port and silently moves:

selected backend port via sequential scan  port: 3777  startPort: 3773

Every client pinned to 3773 (paired remote environments, MCP/CLI clients using a saved URL) then talks to the orphaned backend or gets ECONNREFUSED once it goes away. The remote UI shows Reconnecting to <host> indefinitely. Repeated crashes walk the port forward one step each time (3773 → 3777 → 3778 → 3779 in my case), because each orphan holds its port for a while.

Killing the orphan and relaunching restores 3773. I reproduced this twice on purpose (ss -ltnp showed the orphan pid on 3773 and the new instance on 3777).

Related, not duplicates: #12641 (T3 Connect keeps the link-time origin after the port changes) and #6097 (scanning past 3773 when a service owns it). This issue is about why the port changes after a crash in the first place.

Possible fixes: have the backend exit when its parent dies (PR_SET_PDEATHSIG, or exit on EOF of a parent pipe/IPC channel), and/or detect a stale backend for the same profile on startup and reclaim its port instead of scanning past it.

Impact

Major degradation or frequent failure

Version or commit

0.0.43-nightly.20260926.2282 (also 0.0.43-nightly.20260925.2269)

Environment

Arch Linux, kernel 7.2.4, KDE Plasma (KWin 6.7.5) on Wayland, Electron 44.4.2. Remote client: macOS T3 Code Nightly over Tailscale.

Logs or stack traces

# after the main process (pid 695294) crashed with SIGTRAP and the app was relaunched:
$ ss -ltnp | grep -E ':377[3-9] '
LISTEN 0 511 0.0.0.0:3773 0.0.0.0:* users:(("t3code",pid=695427,fd=3))   # orphaned backend, ppid = systemd --user
LISTEN 0 511 0.0.0.0:3777 0.0.0.0:* users:(("t3code",pid=701542,fd=3))   # backend of the relaunched app

# remote client (macOS) keeps probing the old port:
http.client GET http://100.x.x.x:3773/.well-known/t3/environment  -> connection refused / wrong instance

Workaround

Kill the orphaned backend (ss -ltnp | grep 3773, then kill that pid) and relaunch the app. Pinning T3CODE_PORT=3773 (see #12641) keeps the port stable across normal restarts, but only helps after a crash once the orphan is gone.

No activity

Activity on this issue will appear here.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedfeature request acceptedbugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions