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/desktop
Steps to reproduce
- Start the desktop dev app from a checkout:
vp run dev:desktop --home-dir <some dev home>. - Kill the parent
vpprocess without letting it forward a signal —kill -9 <vp pid>, or close
a terminal that dies before it can signal its children. - Collect the supervisor PIDs and check their parent:
ps -o pid=,ppid=,command= -ax | grep 'dev-electron.mjs' - Touch one of the watched build artifacts:
touch apps/desktop/dist-electron/main.cjs. - Repeat steps 1 and 2 a few times without cleaning up in between.
Expected behavior
This is the maintainers' call. Two directions, offered for discussion rather than as a proposal:
have the supervisor exit when its parent goes away, and/or extend cleanupStaleDevApps() to reap
stale supervisors of the same dev root as well as their apps.
Actual behavior
apps/desktop/scripts/dev-electron.mjs handles SIGINT, SIGTERM and SIGHUP and shuts down
cleanly (:261-269). It has no parent-death watch, so when the parent vp process dies without
forwarding a signal the supervisor is reparented to ppid 1 and keeps restarting Electron on the
next file change (:188-202, debounce :50).
cleanupStaleDevApps() (:92-100, called at startup on :258 and twice inside stopApp(), at
:168 and :177 — so on every debounced restart via :197, not only on shutdown via :247)
only clears stale Electron apps of the same dev root, via
pkill -f -- --t3code-dev-root=<desktopDir>. It does not clear stale supervisors. Several
orphans therefore coexist, each restarting Electron and each killing the others' window on its own
startup, all against the same T3 home.
Stopping the three orphans by their captured PIDs let the next run start cleanly with the same
database: POST /oauth/token returned 200 once and zero SessionBootstrapError.
The 401 that surfaces while orphans are running is filed separately as #19110: this issue is
the stale process, that one is why the symptom is undiagnosable.
One note while reading :97: that line uses pkill -f with the worktree path as the pattern,
which is the exact shape AGENTS.md forbids contributors in "The three ways to hurt yourself",
point 1 ("Your own agent process has this worktree's path in its argv"). Whether the script itself
should be held to that rule is a separate question; flagging it because an agent that reads
AGENTS.md and then this script gets contradictory guidance.
Impact
Major degradation or frequent failure
Version or commit
Environment
macOS 26.3.2 (Darwin 25.3.0), Apple Silicon; Node 24.13.1; pnpm 11.10.0; vp 1.1.0 — the global
install resolved from the bare vp in step 1 (command -v vp → /opt/homebrew/bin/vp,
vp --version → vp v1.1.0). The checkout also ships its own ./node_modules/.bin/vp, which
reports vp v1.0.0; that one was not used for this run.
Logs or stack traces
$ ps -p <pid> -o ppid=
# three `node .../dev-electron.mjs` processes, each reporting ppid 1
# after stopping those three by their captured PIDs, same run, same database:
# POST /oauth/token -> 200 (1 occurrence)
# SessionBootstrapError -> 0 occurrencesWorkaround
Before each start, check that no dev-electron.mjs is running and that the dev ports are free,
and stop a run by the PID of the vp process plus the supervisor PIDs collected at startup.
Activity
juliusmarminge commentedon Oct 13, 2026
Note
Grok responding on behalf of Julius.
Confirmed on main. This only affects the desktop dev workflow (
dev:desktop), not shipped builds. Production backend orphaning is tracked separately in #13747.What main does in
apps/desktop/scripts/dev-electron.mjs:SIGINT/SIGTERM/SIGHUP(:261-269). Nothing watches for parent death, so after akill -9ofvpit is reparented to PID 1, and the next file change still runsscheduleRestart()(:183).cleanupStaleDevApps()(:92-100) only runspkill -f -- --t3code-dev-root=…, which matches Electron apps and not other supervisors. Orphaned supervisors therefore pile up and fight over the same T3 home. [Bug]: desktop dev: stale backend produces an HTTP 401 on /oauth/token with no actionable cause #19110 is the 401 this causes.The workaround is in the report: before restarting, kill any leftover
dev-electron.mjsprocesses.Closed PR #8736 already addresses the root cause. It moves the supervisor under
dev-runneras a sibling process group and drops thepkill -fcleanup. It was closed during a stale-PR sweep and not on its merits, so it's the likely starting point for a fix. Keeping this open as a dev-tooling bug.