# Troubleshooting Start with `herdr_doctor`. Its `FAIL` lines name the fix. Everything below assumes the doctor output. ## Error codes | Code | Meaning | Fix | |---|---|---| | `HERDR_UNAVAILABLE` | Binary missing or not executable | Install herdr or set `herdrBin` / `HERDR_BIN`; check `herdr --version`. | | `HERDR_TOO_OLD` | Client below `0.9.0`, or version unparseable | Upgrade herdr; reopen the pane. | | `HERDR_PROTOCOL` | Non-JSON output or a malformed envelope | Run the same command in a terminal; check for shell noise in `herdr` output. | | `AGENT_NOT_FOUND` | Name/pane no longer exists | `herdr_list_agents`; the session file may still be readable via a retained record. | | `PANE_GONE` | Pane closed under us | Re-`spawn` or `herdr_resume` (future); inspect `~/.dsh/herdr/tasks//`. | | `AGENT_BLOCKED` | Target is waiting at an approval/question | Ask the user, then `herdr_message_agent`. | | `AGENT_STALLED` | Prompt was written but no turn started (after one retry) | Inspect the pane; the text may have been lost. Do not blind-resend. | | `SPAWN_REFUSED` | `enabled:false`, boot failure, or start rejection | Read the message; fix config or inspect the new tab. | | `CONCURRENCY_LIMIT` | `maxParallelAgents` reached and the queue wait expired | Close a finished agent, raise `queueTimeoutMs`, or raise the cap. | | `CWD_NOT_ALLOWED` | `cwd` outside `allowCwd` | Add the directory deliberately. | | `TASK_NOT_FOUND` | Handle matches no record and no live agent | `herdr_list_agents`. | | `TASK_NOT_OWNED` | Refused to mutate a pane the plugin did not create | Use the Herdr UI, or spawn through the plugin. | | `NO_TRANSCRIPT` | The kind has no pi session file | Only kind=pi has a transcript; use `herdr_get_agent_result` for pane text. | | `VALIDATION_ERROR` | Bad argument, unsupported flag, unresolved alias | Read the `fix:` line; aliases come from `model-aliases.md`. | | `TIMEOUT` | CLI call or wait budget expired | A timed-out delegation is still alive; call `herdr_get_agent_result(wait:true)`. | | `ABORTED` | The tool call was cancelled | The plugin sends Escape to an owned agent; check its status. | | `STORE_UNAVAILABLE` | State lock/permission problem | Check `~/.dsh/herdr` ownership; remove a stale `.lock` if no DSH is running. | | `HERDR_UNAVAILABLE` with `phase: connect` | `transport: socket` could not reach the local socket | Open Herdr once, or use `transport: auto`/`cli`. With `auto` the plugin degrades silently. | ## Symptom: tools are not listed 1. Is the bundle in `dsh.profile.bundles`? (`~/.dsh/profiles//package.json`) 2. Is the patch row composed? `dsh --profile --dump-config | grep -A2 tool-herdr`. 3. Desktop: restart the app once. HMR can fail to pick up a new package from a fresh `file:` install. 4. Check the app log for `tool-herdr` or `dsh-herdr` activation errors. ## Symptom: spawn succeeds, `status=running` forever - `herdr_get_agent_result(wait:true)` again with a larger `timeout_ms`. - Look at the pane: is the child waiting for an approval? Then the status should be `blocked`; if Herdr missed it, `agent read` shows the dialog. - If the provider hit a rate limit, the pi session's last message has `stopReason: error`; harvest returns `failed` with the message. - A pane that is visibly idle but reports `working` is a Herdr state-detection miss. `herdr pane report-agent --source manual --agent pi --state idle` unsticks it. ## Symptom: empty or stale final message - Harvest ignores a session message older than `promptedAt`. `warnings` says so. The child may not have started a turn — check the pane. - `result.md` is the second source; if it is empty too, the result carries a pane tail. - For `agy` and other non-pi kinds there is no session file; pane tail is expected. ## Symptom: `diff` is empty - `cwd` is not a git repo → no diff by design. - The child changed nothing. - The repo was dirty before the spawn; `dirtyAtStart` lists those files. The patch still includes them, so subtract them when reviewing. ## Symptom: alias not found ```bash pi --list-models grok ``` Use the exact `provider/model` from the output, or add a row to `~/.pi/agent/model-aliases.md`. The plugin deliberately does not fuzzy-match. ## Symptom: agy refuses model `kind=agy` rejects `model` and `thinking` (its CLI does). Omit them; pass agy's own flags through `agent_args`. ## Symptom: socket transport behaves differently from the CLI `transport: auto` degrades to CLI only on a **connect** failure. An I/O failure mid-request surfaces as `HERDR_UNAVAILABLE` instead of retrying, because retrying a mutation could apply it twice. Switch to `transport: cli` to confirm whether the socket is the problem, and run `herdr status` for protocol drift. ## Symptom: a remote machine is refused - `machine "x" is not enabled` → add the label to `machines`. - `profile desktop is managed exclusively by the Electron application` → do not use `dsh plugin` for the desktop app; use **Plugins → Add plugin** and enter the npm package name (`dsh-herdr@0.11.1`) or the checkout directory. - `The path does not exist or is not a valid plugin package` → a `.tgz` file is not a directory; enter the npm package name instead, or point at the built checkout directory. - `has no file access configured` → add `machineTargets: ["label=user@host"]` for SSH, or `sharedFilesystem` if the paths are mounted. - SSH failures: `BatchMode=yes` means no password prompt. Check `ssh -o BatchMode=yes true` works with your key/agent and that the host key is trusted. The remote shell must be POSIX (`sh`, `cat`, `mkdir -p`, `stat`). Windows remote hosts are not supported. - `herdr --machine