block / block/buzz

Preset harnesses spawn without their declared args (devin, cursor, omp, grok, openclaw)

Open
#4,764 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

## Summary

Every harness in `PRESET_HARNESSES` spawns without the args it declares. For presets whose ACP mode is a subcommand, the harness starts in interactive mode on a stdio pipe and exits immediately, so the whole agent pool fails to start.

Reproduced on **v0.5.4** (latest release) with the Devin preset. Present on `main` at `bc9e6528`.

## Symptom

```
=== starting Bumble (a0955750...) at 2026-08-04T17:01:09 ===
INFO buzz_acp: buzz-acp starting: relay=wss://... agent_cmd=/Users/me/.local/bin/devin mcp_cmd= ... agents=10
ERROR buzz_acp: agent initialize failed: Agent process exited unexpectedly agent=0
ERROR buzz_acp: agent initialize failed: Agent process exited unexpectedly agent=1
...
Error: all 10 agents failed to start — cannot continue
```

Note the two spaces after `agent_cmd=...devin` — the args slot is empty.

Confirming the two invocations directly:

```console
$ echo '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}' | devin
Error: Scrollback error: io error # TUI on a pipe, exits

$ echo '{...same...}' | devin acp
{"jsonrpc":"2.0","id":0,"result":{"protocolVersion":1,"agentCapabilities":{...}}} # works
```

`buzz-acp` itself defaults correctly (`--agent-args [env: BUZZ_ACP_AGENT_ARGS=] [default: acp]`). Desktop overrides that default with an empty value.

## Root cause

`default_agent_args` in `desktop/src-tauri/src/managed_agents/discovery.rs` matches builtins only:

```rust
fn default_agent_args(command: &str) -> Option> {
match normalize_command_identity(command).as_str() {
"goose" => Some(vec!["acp".to_string()]),
"codex" | "codex-acp" | "claude-agent-acp" | "claude-code-acp" | "claude-code"
| "claudecode" | "buzz-agent" => Some(Vec::new()),
_ => None, // every preset lands here
}
}
```

`PRESET_HARNESSES` is a second, independent source of truth for the same fact, and it is never consulted on the spawn path. `devin`, `cursor-agent`, `omp`, `opencode`, `kimi`, `openclaw` all declare `args: &["acp"]`; `grok` declares `&["agent", "--always-approve", "stdio"]`. All resolve to `None`.

Failure path for an affected record:

1. `record.agent_args` is `[]` → `instance_has_args == false` in `resolve_effective_harness_descriptor` (`readiness.rs:151-162`)
2. `record.runtime` is unset → `lookup_loaded_harness_by_id("")` returns `None`, so the registry tier is skipped
3. Falls through to `normalize_agent_args("devin", [])` → `default_agent_args` returns `None` → `[]`
4. `runtime.rs:573` sets `BUZZ_ACP_AGENT_ARGS = ""`, overriding buzz-acp's `[default: acp]`
5. Bare `devin` spawns and exits

Step 2 is what makes this reachable. An agent pinned to a preset by command rather than by runtime id never touches the registry tier that would have supplied the args. The affected records here look like:

```json
{
"agent_command": "devin",
"agent_command_override": "devin",
"agent_args": [],
"acp_command": "buzz-acp"
}
```

with no `runtime` key at all.

## Why tests did not catch it

`devin_preset_uses_official_native_acp_invocation` asserts `entry.default_args == vec!["acp"]` and passes. `preset_catalog_entry` calls `normalize_agent_args(def.command, def.args)` with args already populated, so the non-empty branch returns them unchanged. The catalog never exercises the empty-args path that spawn takes.

## Relationship to #4631

#4631 fixed exactly this class of bug one field over — "Preset harnesses invisible. `known_acp_runtime_exact()` only searches `KNOWN_ACP_RUNTIMES` (builtins). Preset harnesses such as OpenClaw live in `PRESET_HARNESSES`, so the destination lookup returned `None`." That added a three-tier resolver for the harness **command**. The **args** kept the builtin-only blind spot.

## Impact

Any agent using a preset harness pinned by command. Presets with a subcommand ACP mode (devin, cursor, omp, opencode, kimi, openclaw, grok) fail to start entirely. Adapter presets (amp, hermes) declare no args and are unaffected in practice.

## Workaround

Set `agent_args` explicitly on the record so the `instance_has_args` branch wins:

```json
"agent_args": ["acp"]
```

Setting `"runtime": "devin"` also works, via the registry tier.

## Fix

PR #4765 adds `preset_args_for_command` and consults `PRESET_HARNESSES` as tier 2 of `default_agent_args`, mirroring `canonical_harness_command`.

## Environment

- Buzz Desktop v0.5.4 (macOS 15.5, arm64)
- Devin CLI 3000.3.27

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.