pingdotgg / pingdotgg/t3code

[Bug]: `t3 update` across a service-launcher protocol bump leaves the service crash-looping ("Service state is invalid or unsupported") while reporting success

Open
#12,627 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accepted bug via-triage
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/server

Steps to reproduce
  1. macOS, background service installed on t3 0.0.42 (service launcher protocol 2).
  2. Run t3 update --channel nightly --yes to 0.0.43-nightly.20260919.1962 (service launcher protocol 3).
  3. The update reports success: Background service restarted on 0.0.43-nightly.20260919.1962.
Expected behavior

The service starts on the new version, or the update refuses with a clear message before touching the service.

Actual behavior

The service never comes up. launchctl print gui/$UID/com.t3tools.t3code.service shows state = spawn scheduled, last exit code = 1, and launchd respawns it every 5 s indefinitely. Nothing listens on the port; every paired client is disconnected until someone intervenes on the server machine.

~/.t3/runtime/service-state.json after the update:

{ "protocol": 2, "activeVersion": "0.0.43-nightly.20260919.1962" }

Root cause:

  • t3 update performs the service switch in the old CLI's process (apps/server/src/cli/update.ts ~L545: "The service switch runs in this process against the target version … rather than through the target's own CLI").
  • install() then writes service-state.json with the old CLI's compile-time SERVICE_LAUNCHER_PROTOCOL (apps/server/src/cloud/bootService.ts ~L861) while pointing the unit at the new binary.
  • The new launcher's readServiceState (apps/server/src/serviceLauncher.ts ~L186) rejects any protocol other than its own and throws Service state is invalid or unsupported. There is no forward migration.

#11940 added a preflight that blocks the in-client (remote) update path under a legacy launcher, but the CLI update path, which docs/user/background-service.md recommends, has no such check.

Suggested fixes:

  • Have the launcher accept and migrate older state documents when the shape is compatible (protocol 2 → 3 is the same two fields).
  • Or have t3 update delegate the service switch to the target version's CLI when the protocols differ, or refuse with the same message the remote preflight uses.
Impact

Blocks a workflow (the background service is down until manually repaired; the update reports success)

Version or commit

0.0.42 → 0.0.43-nightly.20260919.1962

Environment

macOS 26.6 (Darwin 25.6.0), arm64, background service via launchd

Logs or stack traces
# boot-service.log, repeating every 5 s
[service-launcher] Service state is invalid or unsupported.
[service-launcher] Service state is invalid or unsupported.
[service-launcher] Service state is invalid or unsupported.
Workaround

Run t3 service install with the newly installed CLI. It rewrites service-state.json with the new protocol and the service starts.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in apps/server/src/cli/update.ts around line 545 and apps/server/src/cloud/bootService.ts around line 861; trace how the old CLI switches to the target service version and writes service-state.json. Then inspect apps/server/src/serviceLauncher.ts around line 186 and compare the protocol handling with the preflight from #11940. Done means a protocol-bump update starts the target service successfully or refuses before changing it with a clear message.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.