Skip to content

First desktop launch after updating to nightly 20261101.4035 on macOS reports every provider CLI "not found on PATH" until relaunch #28714

Open

Description

@seanmantey

What happened

After the desktop app updated to 0.1.7-nightly.20261101.4035, the first launch reported every enabled provider (Claude, Codex, Grok) as not found on PATH, though all CLIs are in ~/.local/bin and ~/.grok/bin and resolve in the login shell (zsh). The morning nightly worked. Quitting and relaunching fixed it.

Diagnosis

Regression from #28556.

  • installIntoProcess (apps/desktop/src/shell/DesktopShellEnvironment.ts ~L620-652) publishes the cached env only on a cache hit, forks refresh, and returns true unconditionally, even on a cache miss.
  • DesktopBackendConfiguration.ts ~L786 passes that as shellEnvironmentPrepared, so fixPath (apps/server/src/os-jank.ts ~L101) skips hydratePosixPath. Server starts with PATH=/usr/bin:/bin:/usr/sbin:/sbin.
  • Provider probes fail. The fresh snapshot arrives ~0.8s later and DesktopTelemetryReceiver (~L240) applies it to process.env, but nothing re-probes providers, so "not found" sticks for the session.
  • Next launch has the cache, so it works.

Possible fixes: return false on cache miss, or re-run provider/CLI discovery when a discovered: true snapshot arrives.

Steps to reproduce

  1. macOS, provider CLIs only on a user-shell PATH dir (e.g. ~/.local/bin).
  2. Delete ~/.t3/userdata/shell-environment-cache.json (simulates first launch after update).
  3. Open T3 Code (Nightly) from Dock/Finder.
  4. Settings > Providers: all enabled providers show "not found on PATH".
  5. Quit and relaunch: providers detected.

Version

0.1.7-nightly.20261101.4035 (desktop app, tag v0.1.7-nightly.20261101.4035, commit 80120b1). Earlier nightly on the morning of 2026-11-01 was unaffected.

Environment

macOS (Darwin 27.2.0) arm64, T3 Code (Nightly) desktop app with its local server, login shell zsh.

Evidence

- Failing launch desktop trace: installIntoProcess 0 ms at 15:23:33.95Z; refresh 1448 ms; publish at 15:23:35.40Z. Earlier builds: installIntoProcess blocked ~1.0-1.5 s.
- Provider status caches all written 15:23:34.6Z (before publish) with installed:false, status:error.
- Server exec-time env: PATH=/usr/bin:/bin:/usr/sbin:/sbin.
- shell-environment-cache.json created 15:23 with full PATH; after relaunch all providers ready at 15:32:33Z.

Related issues

#28556 (cause). Same symptom, different causes: #10534, #26372, #10728.

Fix applied or workaround

Quit T3 Code fully (Cmd+Q) and relaunch; the second launch uses the cache the first one wrote.

Filed by

Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage.

Activity

  1. kestereverts commented on Nov 1, 2026

    @kestereverts

    Confirming this on a second machine, with a note on how often it can happen.

    Environment: T3 Code (Nightly) desktop app 0.1.7-nightly.20261101.4035 (tag at 80120b1) with its local server, macOS (Darwin 25.6.0) arm64, login shell zsh. codex is in /opt/homebrew/bin, claude is in ~/.local/bin and /opt/homebrew/bin.

    Failing launch, restarted by installing the update (UTC):

    19:40:20.549  installIntoProcess  0.2 ms
    19:40:20.583  backendInstance.start
    19:40:20.997  provider status written: installed=false, status=error
    19:40:21.844  publish (refresh took 1296 ms)
    

    The server process had PATH=/usr/bin:/bin:/usr/sbin:/sbin. Providers were still "not found" about 5 minutes later.

    Cmd+Q and relaunch:

    19:45:37.105  installIntoProcess  2.4 ms
    19:45:37.107  publish (from the cached environment)
    19:45:37.130  backendInstance.start
    19:45:37.586  provider status written: codex and claudeAgent ready
    

    The server process PATH included both directories.

    How often it can happen: at this tag the cache key is platform, home directory, SHELL and ZDOTDIR (DesktopShellEnvironment.ts:566), with no app version. So this should not recur on every update. It needs a cache miss: the first launch of a build with #28556 where no cache exists yet, or after one of those values changes or the cache file is removed. Anyone updating to a build with #28556 from an older one should hit it once, which is probably why it reads as "after an update".

    Filed by Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage.

  2. kestereverts commented on Nov 1, 2026

    @kestereverts

    Additional data point from a second affected Mac on the same build (Darwin 27.0.1, arm64), which also shows that refreshing providers doesn't recover from this state.

    The desktop app launched at 16:06:26 UTC and hit the same race: backendInstance.start at 16:06:26.313, provider status written as not found at 16:06:26.98, publish at 16:06:28.258. The server process PATH is still /usr/bin:/bin:/usr/sbin:/sbin nearly 4 hours later.

    ws.rpc.server.refreshProviders ran at 19:39:56 and 19:50:28 UTC, and both exited Success. The Claude status cache still has checkedAt 16:06:26.982Z, and the UI still showed "not found on PATH" at 19:51:59. I haven't traced why in the source. For now, a full quit and relaunch is the only recovery I've seen work.

    Filed by Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage.

  3. added a commit that references this issue on Nov 1, 2026
  4. 0pilatos0 commented on Nov 2, 2026

    @0pilatos0
    Contributor

    Another hit on 0.1.7-nightly.20261102.4066 (macOS 27.0.0 arm64, desktop app with local server, zsh), plus why refreshing providers doesn't recover.

    Same race: this was the first launch on a #28556 build, so there was no shell-environment-cache.json. installIntoProcess took 0.2 ms at 10:17:55.33Z, the backend started with PATH=/usr/bin:/bin:/usr/sbin:/sbin, and applyShellEnvironment ran on the server at 10:17:56.12Z. Claude and OpenCode show "not found on PATH". A re-check at 10:18:33Z still failed.

    Cause of the stuck state for Claude: since #28410 (ddfc4a9), ClaudeDriver.ts:137 builds processEnv via mergeClaudeProcessEnvironment(config, environment, process.env), which spreads process.env into a new object once, when the driver is created. Status checks and sessions keep using that copy, so the live PATH patch never reaches Claude. Re-probing on a discovered snapshot won't be enough. The drivers need rebuilding, or shellEnvironmentPrepared should stay false on a cache miss.

    The login-shell probe is fine here: zsh -ilc exits 0 in 0.9 s with the full PATH.

    Filed by Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage.

  5. imaxisXD commented on Nov 2, 2026

    @imaxisXD

    Another hit on 0.1.7-nightly.20261102.4066 (macOS 27.2 arm64, desktop app with its local server, zsh), Claude only. claude comes from the native installer, in a user-level bin directory on the login-shell PATH.

    The update was from a build that predates #28556 (the previous launch still blocked on the login-shell probe), so this was the first launch with no shell-environment-cache.json. Timeline (UTC) from the desktop and server traces:

    11:18:19.006  ElectronUpdater.quitAndInstall
    11:18:23.804  desktop installIntoProcess 0.2 ms, no cached publish
    11:18:23.845  backendInstance.start (server exec env PATH=/usr/bin:/bin:/usr/sbin:/sbin)
    11:18:25.086  ClaudeDriver.create / mergeClaudeProcessEnvironment
    11:18:25.092  runClaudeCommand (claude --version): PlatformError: NotFound: ChildProcess.spawn
    11:18:25.950  desktop refresh done (2146 ms), publish
    11:18:25.958  server applyShellEnvironment: Success
    11:25:53.609  runClaudeCommand (claude --version): still NotFound
    every ~10 s   "Claude capability probe failed." from probeClaudeWorkspaceSnapshot
    11:28:29      after Cmd+Q and relaunch: cached publish before backend start, ClaudeDriver.create 11:28:30, claude --version succeeds
    

    This matches the cause in the comment above: the live process.env was patched at 11:18:25.958, but the Claude driver's copy from 11:18:25.086 kept the launchd PATH. Both the status check and the capability probe use that copy, so the probe kept failing every 10 s.

    As of today main is not fixed: 4 commits past the 4066 tag, mergeClaudeProcessEnvironment (apps/server/src/provider/Drivers/ClaudeHome.ts, as changed by #29169) still spreads hostEnvironment once when the driver is created. Same race for other providers: #28890.

    Workaround: Cmd+Q and relaunch once. To avoid it after a later cache miss, I also set the Claude instance's binary path to the installer's stable claude symlink. That was after the relaunch, so it is not tested as a way to recover a stuck backend.

    Filed by Claude Code (Claude Opus 5.5, claude-opus-5-5) via t3 triage.

  6. shanghaiEric commented on Nov 2, 2026

    @shanghaiEric

    Adding evidence from a downstream localized build based on nightly 4066. This run hit the cache-miss + failed background discovery case, rather than a successful late PATH update.

    Environment and observed failure

    • macOS 27.2 (26B123), Apple Silicon, zsh, desktop with its bundled local server.
    • Installed build: 0.1.7-nightly.20261102.4066.zh.2 (self-built localization fork). The installed ASAR contains the asynchronous shell-discovery implementation from fix(desktop): discover shell environment without blocking startup #28556; this has not been reproduced with an unmodified official binary.
    • Codex CLI 0.166.0 is installed at /opt/homebrew/bin/codex and runs successfully from the terminal.
    • After updating and relaunching, T3 reports: “Could not start Codex CLI (codex). Check Settings → Providers → Codex → Binary path on the server.”
    • ~/.t3/userdata/shell-environment-cache.json was absent when inspected after the failure. The trace has no cached publish before backend startup.
    • The desktop and bundled server's exec-time PATH was /usr/bin:/bin:/usr/sbin:/sbin. This is launch-environment evidence, not a direct read of later JavaScript process.env mutations.

    Relevant trace events on 2026-11-02, UTC:

    13:42:01.849  desktop.shellEnvironment.installIntoProcess   0.31 ms
    13:42:01.851  login-shell probe begins
    13:42:07.164  DesktopShellEnvironmentCommandTimeoutError
                 probe=login-shell executable=zsh timeoutMs=5000
                 observed probe span duration: 5313.52 ms
    13:42:07.172  desktop.shellEnvironment.publish
    13:42:07.173  server applyShellEnvironment (Success)
                 background refresh total: 5322.04 ms
    

    Later, running zsh with the minimal system PATH and stdin disconnected completed in approximately 1.9–2.0 seconds and resolved both Codex and Node. The original reason for exceeding five seconds is not established; no stack of the timed-out shell was captured.

    Why this variant matters

    In the implementation introduced by #28556, installIntoProcess forks discovery and returns true on a cache miss. The server consequently skips its own PATH hydration. If discovery fails, refresh can publish the inherited/degraded environment with discovered: false, writes no successful cache, and has no retry in this path.

    Thus, re-probing providers only after a successful snapshot would not cover this case. Likewise, the “relaunch using the cache just created” workaround does not apply to this failed run: no cache was created. A subsequent launch might succeed if shell discovery succeeds, but that has not been verified here.

    This overlaps the timeout recovery issue in #10534, now under the asynchronous startup flow. I also saw #22286, whose stated scope is failed capture and desktop SSH recovery.

    Proposed scope for discussion

    We would like to prepare a focused local fix, preserving fast startup when a usable cache exists, while ensuring a cache miss / failed capture has a bounded recovery path and providers do not stay bound to an unusable startup environment.

    Would maintainers prefer awaiting bounded discovery before provider initialization on a cache miss, or keeping initialization asynchronous with explicit failure recovery and provider-environment refresh? Is there already work covering both this timeout case and the successful-but-late snapshot case above that we should coordinate with?

    No application code or shell configuration was changed during this investigation. No PR is being opened yet. This comment was prepared and posted with Codex at the affected user's request; private logs and credentials are omitted.

  7. Cjericho4 commented on Nov 2, 2026

    @Cjericho4

    Another hit on 0.1.7-nightly.20261102.4080 (macOS 27.0.0 arm64, T3 Code Nightly desktop app with its local server, login shell zsh). Claude only stayed missing. Grok still ran in the same server.

    claude is Claude Code 2.1.316 at ~/.local/bin/claude (symlink to the native installer under ~/.local/share/claude/versions/). The Claude provider binary setting is the bare name claude. A zsh -ilc PATH includes ~/.local/bin and ~/.grok/bin.

    This was a cold shell cache for the launch. Timeline (UTC), from the desktop trace, server trace, and the server process environment:

    • 16:06:33.581 desktop.shellEnvironment.installIntoProcess returns in 0.16 ms
    • 16:06:33 server process starts; ps environment is PATH=/usr/bin:/bin:/usr/sbin:/sbin
    • 16:06:34.355 mergeClaudeProcessEnvironment (ClaudeDriver spreads process.env here)
    • 16:06:34.605 login-shell refresh finishes (~1023 ms) and writes shell-environment-cache.json with ~/.local/bin on PATH
    • 16:06:35.495 resourceTelemetry.desktopTelemetryReceiver.applyShellEnvironment updates the live server environment
    • 16:07:30, 16:07:35, 16:07:39 checkClaudeProviderStatus fails in 1–3 ms, errorTag: PlatformError (NotFound)
    • 16:08:18.732–16:08:18.785 Claude turn fails with Claude Agent CLI (claude) was not found on PATH.

    The late PATH update reached the live server environment. A Grok child started after it inherited ~/.local/bin. Grok's driver keeps that live process.env when the instance has no environment overrides. Claude's copy was already taken, so later probes still spawn claude with the GUI PATH.

    Same race as the 4066 reports above. Build is nightly 0.1.7-nightly.20261102.4080, source commit 47f2c8d29e981c7723467efe137ee19e91df924e. Workaround for this launch is Cmd+Q and relaunch, now that the cache file exists.

    Noted from T3 triage on this machine. Drafted by Grok 4.7.

  8. OCPdev25 commented on Nov 2, 2026

    @OCPdev25

    Another hit on 0.1.7-nightly.20261102.4080 (macOS, Apple Silicon, desktop app with its local server, login shell zsh). Adding a second data point from this machine plus a lighter recovery path:

    • After the update, Settings showed both Codex and Claude as "Not found" with the can't-start banner, even though both CLIs are installed (codex via npm at ~/.local/bin/codex, codex-cli 0.166.0; both resolve fine in a terminal). The morning nightly had worked.
    • The bundled server process environment confirmed the race: PATH=/usr/bin:/bin:/usr/sbin:/sbin at exec time, while ~/.t3/userdata/shell-environment-cache.json did get written with the full login-shell PATH (~/.local/bin, ~/.vite-plus/bin, homebrew). So desktop discovery finished late, after the provider probes had already failed, matching the cache-miss timeline above.
    • The codex launcher here is the npm Node shim (#!/usr/bin/env node), so even an absolute binary path can fail on a bare server PATH until node resolves, since node also lives in a user-shell PATH dir on this machine (~/.vite-plus/bin).

    Recovery without quitting the app: toggling the provider off and back on in Settings (Providers) restored both Codex and Claude immediately. That lines up with the stuck-state diagnosis above: enabling recreates the driver, which re-snapshots process.env after applyShellEnvironment had already patched in the hydrated PATH, whereas plain re-checks kept using the driver's stale snapshot.

    So ws.rpc.server.refreshProviders may not recover, but a provider disable/enable does. Worth noting for the workaround text in the issue body, which currently only lists quit and relaunch.

    Filed by GLM-5.3 Flash (opencode-go/glm-5.3-flash) via t3 triage.

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

    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