Model discovery fails on GUI launch — bundled managed node not on discovery subprocess PATH (Linux/macOS)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
On Linux (and almost certainly macOS), when Buzz is launched from the desktop/GUI, agent **model discovery fails** and the model dropdown silently falls back to built-in options with:
> Using built-in model options. Could not load live models for this provider.
The real cause is that the model-discovery subprocess can't find `node`, even though Buzz has downloaded its **own** managed Node runtime. `run_agent_models_command` sets the subprocess `PATH` solely from `login_shell_path()` and never prepends Buzz's bundled managed-node bin dir, so the `#!/usr/bin/env node` ACP adapter (`claude-agent-acp`) dies on launch.
This looks like the Linux/macOS sibling of the Windows PATH work in #2247 — same subsystem, different branch/platform.
## Environment
- Buzz 0.4.22 (AppImage, `Buzz_0.4.22_amd64.AppImage`)
- Linux x86_64 (Ubuntu/Zorin-based, GNOME), app launched from the desktop launcher
- Runtime: **Claude Code** — `claude` CLI v2.1.216, adapter `@agentclientprotocol/claude-agent-acp` v0.60.0
- Bundled managed node present: `~/.local/share/Buzz/runtimes/node/v24.11.0/linux-x64/bin/node`
- `node` provided on this machine only via `nvm`, initialized in `~/.bashrc` **after** the standard non-interactive guard (`# If not running interactively, don't do anything`); `~/.bash_profile` does not source `~/.bashrc`.
## What the user sees
Connect Claude Code, open the agent's model dropdown → *"Using built-in model options. Could not load live models for this provider."* No indication of the real cause. (The "for **this** provider" wording is just the `provider_locked` Claude runtime having `provider: null` — not a red herring worth chasing.)
## Root cause
Model discovery runs `buzz-acp models --json`, which spawns the `claude-agent-acp` adapter — a Node script with `#!/usr/bin/env node`. The subprocess `PATH` comes only from `login_shell_path()`:
`desktop/src-tauri/src/commands/agent_model_process.rs` (`run_agent_models_command`):
```rust
if let Some(ref path) = crate::managed_agents::login_shell_path() {
cmd.env("PATH", path);
}
```
On a GUI launch, the process `PATH` has no `node` (nvm isn't loaded), and `login_shell_path()` runs a **non-interactive** `bash -l -c 'echo $PATH'`, which also lacks `node` because nvm is only initialized in the interactive branch of `~/.bashrc`. So `env` can't find `node`, the adapter never starts, `buzz-acp` exits non-zero, discovery returns `Err`, and `personaModelDiscoveryStatus.ts` shows its generic catch-all message.
Crucially, Buzz already downloaded a working `node` at `buzz_managed_node_bin_dir()` (`managed_node_paths.rs`) — it just isn't placed on the discovery subprocess `PATH`.
## Reproduction
Faithful reproduction of Buzz's exact invocation with the app's real (GUI-launch-derived, node-less) login PATH:
```
$ env -i HOME=$HOME PATH="$(env -i HOME=$HOME PATH=/usr/bin:/bin bash -l -c 'echo $PATH')" \
BUZZ_ACP_AGENT_COMMAND="$HOME/.local/share/Buzz/node-tools/bin/claude-agent-acp" \
BUZZ_ACP_AGENT_ARGS="" \
buzz-acp models --json
/usr/bin/env: 'node': No such file or directory
error: agent communication failed: Agent process exited unexpectedly # exit 1
```
Prepend the bundled managed node and it succeeds (exit 0, full model list — Default/Opus/Fable/Sonnet/Haiku):
```
$ PATH="$HOME/.local/share/Buzz/runtimes/node/v24.11.0/linux-x64/bin:$PATH" buzz-acp models --json
{ "agent": { "name": "@agentclientprotocol/claude-agent-acp", ... }, "stable": { "configOptions": [ ... ] } }
```
## Suggested fix
For agent-spawn / model-discovery subprocesses, prepend `buzz_managed_node_bin_dir()` to `PATH` (before the `login_shell_path()` value) whenever it exists — Buzz went to the trouble of bundling a private Node precisely so it wouldn't depend on the user's system/nvm node, but the discovery/spawn paths don't use it. This generalizes the PATH hardening in #2247 to Linux/macOS. Applying the same to `spawn_agent_child` would prevent the same failure at actual agent-run time, not just discovery.
Secondary, optional: surface the underlying stderr (e.g. `env: node: No such file or directory`) in the model-discovery status instead of the fully generic fallback, so this class of failure is diagnosable without reproducing the subprocess by hand.
## Workaround (for anyone hitting this)
Symlink `node` onto a dir that's on the login PATH, e.g.:
```
ln -s ~/.nvm/versions/node//bin/node ~/.local/bin/node
```
then fully restart Buzz (`login_shell_path()` is cached per-process).
Contributor guide
Assessment
This issue has not been assessed yet.