Skip to content

Bug Report: managed-agents.json corruption, duplicate entries, and empty model dropdown when using custom ACP harnesses #5155

Description

@Jross1719

Bug Report: managed-agents.json corruption, duplicate entries, and empty model dropdown when using custom ACP harnesses

Environment

  • OS: macOS 15.x (Apple Silicon, M3 Pro / M5 Pro)
  • Buzz Desktop: latest (build from xyz.block.buzz.app)
  • ACP harness: custom SSH wrapper pointing to acp-claude-code (v0.8.0) on remote VPS
  • ACP library: @zed-industries/agent-client-protocol@0.1.2

Issue 1: managed-agents.json gets corrupted when changing a harness

Steps to reproduce:

  1. Open Buzz Desktop
  2. Go to an agent's settings → change its harness (e.g., from buzz-acp to acp-claude-wrapper)
  3. Close and reopen Buzz

Expected: Only the selected agent's acp_command field changes. All other agents and entries remain intact.

Actual: Buzz overwrites the entire managed-agents.json file. In practice, this causes:

  • Duplicate entries — every harness change adds a new entry for the same agent without removing the old one. After a few changes, each agent appears twice (or more) in the JSON array.
  • Lost entries — if the file is rewritten with incomplete data, agents vanish entirely. Buzz then dumps the file to managed-agents.json.invalid and all agents disappear.

Evidence: The file at ~/Library/Application Support/xyz.block.buzz.app/agents/managed-agents.json accumulates duplicate entries. After switching harnesses on 4 agents, the file contained 32 entries for 16 unique agents. Each duplicate had a different slug UUID but the same display_name, causingBuzz to either pick the wrong one or reject the config.

Root cause (likely): Buzz's harness-switch handler rewrites the entire agent store on every change. It does not deduplicate by display_name or slug, and it does not validate that all existing entries are preserved. The write is also not atomic — if interrupted, the file can be truncated to 0 bytes.

Workaround attempted: Locking the file with chflags uchg prevents Buzz from overwriting it, but then Buzz can't write its own runtime state (PID tracking, last-started timestamps), which causes agents to fail to spawn with commit managed-agents.json: Operation not permitted (os error 1).


Issue 2: Empty model dropdown when using a custom ACP harness

Steps to reproduce:

  1. Set an agent's harness to a custom ACP bridge (e.g., acp-claude-wrapperacp-claude-code on VPS)
  2. Open the agent's settings in Buzz Desktop
  3. Click the model dropdown

Expected: The dropdown shows available models from the ACP bridge (e.g., Claude models via OpenRouter or Anthropic).

Actual: The dropdown is empty. No models are listed.

Root cause: The ACP library (@zed-industries/agent-client-protocol@0.1.2) has a hardcoded switch statement in AgentSideConnection that only recognizes 6 methods: initialize, session/new, session/load, authenticate, session/prompt, session/cancel. Any other method (including claude/listModels or /models) hits default: throw RequestError.methodNotFound(method).

The compiled code at node_modules/@zed-industries/agent-client-protocol/dist/acp.js lines 57-60:

case schema.AGENT_METHODS.session_cancel: {
    const validatedParams = schema.cancelNotificationSchema.parse(params);
    return agent.cancel(validatedParams);
}
default:
    throw RequestError.methodNotFound(method);


There is no mechanism for agents to advertise or expose available models. The protocol schema (`schema.json`) has no `listModels` or `models` method defined. This is a protocol-level gap  the ACP spec doesn't define a model-listing endpoint, so no ACP agent can expose models to the client.

**Impact:** Any custom ACP harness (Claude Code, Codex, custom LLM bridges) cannot show models in Buzz Desktop. Users are forced to either:
- Use Buzz's built-in harnesses (which have their own model lists hardcoded)
- Manually configure model IDs in agent settings (if the field exists)

---

## Issue 3: Agents spawn and immediately die (~5 seconds) when using a custom ACP harness

**Steps to reproduce:**
1. Set an agent's harness to a custom ACP bridge
2. Click "Spawn" or send a message to the agent in Buzz Desktop
3. Watch the agent status

**Expected:** Agent spawns, connects to the ACP bridge, and stays alive until the conversation ends or is manually stopped.

**Actual:** Agent spawns, establishes the initial ACP handshake (initialize succeeds), then dies within ~5 seconds. The agent shows as "connected" briefly, then disappears from the sidebar.

**Evidence from logs** (`~/Library/Application Support/xyz.block.buzz.app/agents/logs/`):
- The `buzz-acp` process logs show `buzz-acp starting: ... agent_cmd=<wrapper_path> ...` then `connected to relay` then `presence set to online`
- After ~5 seconds, the agent process exits without any error message in the logs
- No `buzz-acp stopped` log line  the process is killed externally (by Buzz) after the ACP handshake fails on a subsequent request

**Root cause (likely):** After the `initialize` call succeeds, Buzz Desktop sends a follow-up request (possibly `claude/listModels`, `session/new`, or a heartbeat) that the ACP bridge doesn't handle. The bridge either:
- Returns `Method not found` (because the ACP library rejects unknown methods)
- Crashes because the request payload doesn't match expected schema
- Times out waiting for a response that never comes

Buzz interprets this as a connection failure and kills the agent process.

**Note:** This is partially caused by Issue 2 (no model listing)  if Buzz can't get the model list, it may send an invalid follow-up request that the bridge can't handle.

---

## Issue 4: managed-agents.json is not written atomically

**Steps to reproduce:**
1. Modify `managed-agents.json` while Buzz is running
2. Check the file size and content

**Expected:** Writes are atomic (write to temp file, then rename). No partial writes.

**Actual:** Buzz writes directly to the file. If the write is interrupted (crash, signal, disk full), the file is left in a partial state. In practice, the file has been observed truncated to 0 bytes after a harness switch, causing all agents to vanish.

**Evidence:** Backup files exist at:
- `managed-agents.json.bak` (32 entries, from before the corruption)
- `managed-agents.json.bak.0` through `.bak.2` (previous backups)
- `managed-agents.json.invalid` (Buzz's rejection of a bad config)
- `managed-agents.json.json` (another backup variant)

The presence of multiple backup variants suggests Buzz is trying to recover from write failures but the recovery mechanism is incomplete.

---

## Summary of Required Fixes

| Priority | Issue | Fix |
|----------|-------|-----|
| P0 | managed-agents.json corruption on harness change | Write atomically (temp file + rename). Deduplicate entries by `display_name`. Preserve existing entries on rewrite. Validate all entries have required fields (`relay_url`, `acp_command`, etc.) before writing. |
| P0 | Empty model dropdown | Add a protocol-level model listing mechanism. Either: (a) define a `listModels` method in the ACP schema, or (b) have Buzz query the agent's advertised capabilities and fall back to a configurable model list. |
| P1 | Agents die after ~5 seconds | Improve error handling in the ACP connection lifecycle. When a follow-up request fails, log the error and retry instead of killing the agent. Add a minimum connection timeout before declaring the agent dead. |
| P1 | File locking conflict | Remove the `uchg` lock workaround. Instead, use proper file locking (flock) or atomic writes so Buzz can manage its own state without external interference. |
| P2 | Duplicate entries accumulate | Add a deduplication step on config load. If duplicate `display_name` entries exist, keep the one with the most complete data (most fields populated) and remove the rest. |

---

## Additional Context

- The ACP protocol is designed for code editors (VS Code, JetBrains, Zed) connecting to coding agents. Buzz Desktop is using it as a general-purpose agent harness, which exposes gaps in the protocol (no model listing, no heartbeat, no graceful degradation on connection loss).
- The `@zed-industries/agent-client-protocol` package is deprecated (renamed to `@agentclientprotocol/sdk` v0.4.5). The current version (0.1.2) has known limitations that haven't been addressed.
- Users with custom ACP harnesses (especially Claude Code via subscription credits) are effectively locked out of model selection and reliable agent spawning. This is a significant usability barrier for the intended use case.

---

## Workarounds (for reference)

1. **Don't change harnesses after initial setup** — once configured, avoid UI harness switches to prevent config corruption.
2. **Use Telegram instead of Buzz when Mac is closed**  the VPS Telegram gateway runs independently and doesn't require the Mac to be awake.
3. **Manually fix managed-agents.json**  if it gets corrupted, restore from `managed-agents.json.bak` and re-apply harness mappings. (We have a Python script for this: `python3 /tmp/fix_sobel.py`.)

---

Paste that into the Buzz Desktop GitHub repo issues page. The repo URL is `https://github.com/block/buzz`  verify and adjust if it's different.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions