[Bug]: Desktop starts a second backend against the background service database
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
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
- Configure and start the background server with the default T3 home (for example,
t3 service install/t3 service start, listening on port 3773). - Launch the desktop app as the same OS user without overriding its T3 home.
- The desktop sees that port 3773 is occupied, selects 3774, and starts its embedded backend.
Expected behavior
The desktop must not start a second backend against a database already owned by a running server. It should either reuse/pair with that environment or stop before opening the database and explain how to resolve the conflict.
Actual behavior
The embedded desktop backend opens the same default database, ~/.t3/userdata/state.sqlite, as the background server. Two long-lived server processes then contend for one SQLite database. Authentication, orchestration, and thread creation intermittently fail with HTTP 500 and errors such as:
Primary environment request failed during fetch-session-state (HTTP 500).
database is locked
In the observed failure, the desktop app could not finish loading and the machine became severely resource constrained until it was restarted.
Root cause
Desktop startup treats port ownership and data-directory ownership independently:
resolveDesktopBackendPortscans past occupied port 3773 and chooses another port.- The primary desktop bootstrap still passes the default
environment.baseDir(normally~/.t3) to the embedded backend. - Startup does not check the existing
server-runtime.jsonlease/descriptor before opening the same database.
SQLite WAL permits concurrent readers but does not make two independent long-lived server owners safe. A busy timeout may reduce transient SQLITE_BUSY errors (see #5099), but it does not address duplicate schedulers, WebSocket streams, command processors, or resource usage.
Suggested fix
Before selecting another port or launching the embedded backend, inspect the runtime state for the selected T3 home and probe the advertised environment endpoint. If a live server already owns that home, fail closed before opening SQLite and show a specific recovery message (stop the background service, or use a separate T3 home and connect/pair with the existing environment). Ignore stale runtime state only after the probe confirms it is not live.
Add regression coverage proving that a live owner prevents embedded-backend startup while missing/stale runtime state preserves normal startup.
Impact
- Desktop can fail to open.
- OAuth/session and orchestration writes return HTTP 500.
- Duplicate backends can consume substantial CPU/memory.
- Retrying or adding
busy_timeoutalone masks symptoms without enforcing single ownership.
Version or commit
0.0.34-nightly.20260811.1064
Environment
Linux desktop; background T3 service and desktop app running as the same user with the default T3 home.
Workaround
Stop the background service before launching the desktop app, or launch the desktop with a separate T3 home and connect/pair to the background environment.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at resolveDesktopBackendPort and the primary desktop bootstrap, then inspect the server-runtime.json lease and advertised environment endpoint. Add regression coverage showing that a live owner blocks embedded-backend startup before the database opens, while missing or stale runtime state preserves normal startup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sqlite, typescript
- Domain
- backend, databases, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100