You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
First desktop launch after updating to nightly 20261101.4035 on macOS reports every provider CLI "not found on PATH" until relaunch #28714
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.
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
macOS, provider CLIs only on a user-shell PATH dir (e.g. ~/.local/bin).
Delete ~/.t3/userdata/shell-environment-cache.json (simulates first launch after update).
Open T3 Code (Nightly) from Dock/Finder.
Settings > Providers: all enabled providers show "not found on PATH".
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.
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.
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.
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.
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.
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.
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: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.
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.
Activity
kestereverts commentedon Nov 1, 2026
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.
codexis in /opt/homebrew/bin,claudeis in ~/.local/bin and /opt/homebrew/bin.Failing launch, restarted by installing the update (UTC):
The server process had PATH=/usr/bin:/bin:/usr/sbin:/sbin. Providers were still "not found" about 5 minutes later.
Cmd+Q and relaunch:
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.
kestereverts commentedon Nov 1, 2026
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.startat 16:06:26.313, provider status written as not found at 16:06:26.98,publishat 16:06:28.258. The server process PATH is still /usr/bin:/bin:/usr/sbin:/sbin nearly 4 hours later.ws.rpc.server.refreshProvidersran at 19:39:56 and 19:50:28 UTC, and both exited Success. The Claude status cache still hascheckedAt16: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.
Merge upstream/main (fa31b66)
0pilatos0 commentedon Nov 2, 2026
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.
imaxisXD commentedon Nov 2, 2026
Another hit on 0.1.7-nightly.20261102.4066 (macOS 27.2 arm64, desktop app with its local server, zsh), Claude only.
claudecomes 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:This matches the cause in the comment above: the live
process.envwas 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
mainis not fixed: 4 commits past the 4066 tag,mergeClaudeProcessEnvironment(apps/server/src/provider/Drivers/ClaudeHome.ts, as changed by #29169) still spreadshostEnvironmentonce 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
claudesymlink. 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.
shanghaiEric commentedon Nov 2, 2026
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
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./opt/homebrew/bin/codexand runs successfully from the terminal.codex). Check Settings → Providers → Codex → Binary path on the server.”~/.t3/userdata/shell-environment-cache.jsonwas absent when inspected after the failure. The trace has no cached publish before backend startup./usr/bin:/bin:/usr/sbin:/sbin. This is launch-environment evidence, not a direct read of later JavaScriptprocess.envmutations.Relevant trace events on 2026-11-02, UTC:
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,
installIntoProcessforks discovery and returnstrueon a cache miss. The server consequently skips its own PATH hydration. If discovery fails,refreshcan publish the inherited/degraded environment withdiscovered: 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.
Cjericho4 commentedon Nov 2, 2026
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.
claudeis 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 nameclaude. Azsh -ilcPATH includes~/.local/binand~/.grok/bin.This was a cold shell cache for the launch. Timeline (UTC), from the desktop trace, server trace, and the server process environment:
desktop.shellEnvironment.installIntoProcessreturns in 0.16 mspsenvironment isPATH=/usr/bin:/bin:/usr/sbin:/sbinmergeClaudeProcessEnvironment(ClaudeDriver spreadsprocess.envhere)shell-environment-cache.jsonwith~/.local/binon PATHresourceTelemetry.desktopTelemetryReceiver.applyShellEnvironmentupdates the live server environmentcheckClaudeProviderStatusfails in 1–3 ms,errorTag: PlatformError(NotFound)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 liveprocess.envwhen the instance has no environment overrides. Claude's copy was already taken, so later probes still spawnclaudewith the GUI PATH.Same race as the 4066 reports above. Build is nightly
0.1.7-nightly.20261102.4080, source commit47f2c8d29e981c7723467efe137ee19e91df924e. 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.
OCPdev25 commentedon Nov 2, 2026
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:
codexvia npm at~/.local/bin/codex, codex-cli 0.166.0; both resolve fine in a terminal). The morning nightly had worked.PATH=/usr/bin:/bin:/usr/sbin:/sbinat exec time, while~/.t3/userdata/shell-environment-cache.jsondid 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.#!/usr/bin/env node), so even an absolute binary path can fail on a bare server PATH untilnoderesolves, sincenodealso 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.envafterapplyShellEnvironmenthad already patched in the hydrated PATH, whereas plain re-checks kept using the driver's stale snapshot.So
ws.rpc.server.refreshProvidersmay 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.