Troubleshooting
Symptom, cause, and fix for the most common Orchemax friction points: the reaper, stale locks, PATH, second Chair, permission timeouts, silent hooks, and usage showing zero.
Grep this page by the error string you're seeing — each row is a self-contained symptom/cause/fix triplet.
The reaper reclaimed a session I thought was still running#
- Symptom: locks, a running task, or a worktree from a session disappeared while you weren't watching.
- Cause: the daemon reaps dead sessions on a clock
(
daemon.reap_interval_sec, default 60s). Once a killed/crashed agent's seat looks abandoned, the reaper frees what it held: itsshared_locksrows, its running task row, and — for an isolated checkout — its worktree. - Fix: expected cleanup, not a bug. To stop it entirely (not
recommended), set
daemon.reap_interval_sec: 0.
A shared-path lock won't budge, or orch lock acquire fails#
- Symptom:
orch lock acquire <path> --holder <id>fails, or a stale lock blocks a guard check. - Cause: locks carry a TTL (
--ttl-min, default 15 minutes) — a session that died before releasing leaves the lock held until it expires. - Fix:
orch lock status <path>(or no path, for the full list) showsexpires_at; once expired, any holder can re-acquire it.orch msg stale --older-min 15finds stale unread alerts more broadly.
orch: command not found after install#
- Symptom:
orchisn't recognized in a new shell right after install. - Cause:
orch setupupdates the user PATH, not the current process's PATH — an already-open shell doesn't see the change. - Fix: open a new terminal. If it's still missing, run
orch setup --prune-path --dry-runto see what Orchemax believes is on PATH, thenorch setup --prune-pathto reconcile.
"project already has Chair session … — one Chair per project"#
- Symptom: starting a second interactive Chair on the same project is refused with that exact message.
- Cause: by design, a project runs one interactive Chair at a time
(
ChairOnlyseat claim) — two Chairs racing to dispatch workers on the same project would double-claim work. - Fix: join the existing Chair session, or dispatch with
--force-chairif it's actually dead and the reaper hasn't caught up. Workers never hit this — spawn them withorch task run.
"Outside the Team work schedule…"#
- Symptom: dispatch / spawn fails with a plain sentence about the Team
work schedule (not
plan deny: capability=…). - Cause: Team (or Enterprise) has an enabled weekday window and the company clock is outside those hours, or that weekday is Disabled. Ignored days and empty schedules do not gate.
- Fix: wait for the window, or ask a Team admin to adjust hours /
Ignore the day at orchemax.com/app/schedules.
Then refresh the lease:
orch server entitlements. See Team work schedules.
"every route is cooling, soonest available in Ns, beyond the Ms wait cap"#
- Symptom: a 502 from the local gateway naming every provider as
skipped: in cooldown or circuit open, and a soonest-available time past the wait cap. - Cause: every route in the chain is cooling at once. A 60s cooldown is the quota / rate-limit path (HTTP 429 or 402, or a body saying rate limit, insufficient quota, out of credits); 300s is the unreachable path. A chain of free tiers hits the first one together, which is what a free tier does.
- Read what happened:
<workshop>/.orch/gateway.errcarries one line per failed dispatch —[gateway] dispatch failed model=… class=cooling err=…— and the error text names every provider it tried and why.orch usageshows the attempts; a row witherror_class=coolingis this, not an upstream fault. - Fix: let it wait instead of refusing.
gateway.cooldown_wait_mscaps that wait (0 = the router's 30s default, negative = never wait); 90000 covers a 60s rate-limit cooldown with margin. Restart the gateway after editing (orch gateway service restart) and the startup line reports the cap in effect. Add a paid route to the chain if free tiers are not enough.
"…allows N concurrent worker…" / Chair open-agent cap#
- Symptom: spawn refused because concurrent workers are full, or opening another interactive Chair hits the plan's open-Chair ceiling.
- Cause:
orch.agents.concurrentmeters workers;orch.agents.maxmeters open Chairs (MCP-only Chairs do not consume the worker meter). - Fix: wait for a worker to finish, close an idle Chair seat, or upgrade
the plan. Optional
agents.workersinorch.yamlonly prefers cheap models — it does not raise the cap.
OpenClaude model / MCP permission friction#
- Symptom: picker always shows
orchemax/pareto; ormcp__orch__verify_status has been deniedin dontAsk mode. - Cause / fix: see Common seat tune-ups
(
env.OPENAI_MODELpin;dontAskvsbypassPermissions+mcp__orch__*).
A worker exits 126 or 124#
- Symptom: a dispatched worker's
.orch-agent.logends with exit 126 or 124 and no useful diff. - Cause: 126 = Orchemax detected a headless permission/write denial (the CLI
tried to prompt interactively and couldn't). 124 = it hit
agents.timeout_sec(wall-clock cap) oragents.idle_timeout_sec(no stdout/stderr for that long). - Fix: for 126, make the preset's headless command allow writes without
an interactive prompt — see
configure-agents.md. For 124, raiseagents.timeout_sec/--timeout, or raise/disableagents.idle_timeout_secif the agent is just slow.
A context hook seems to do nothing#
- Symptom:
context.hooks.post_tool/pre_compactistrueinorch.yaml, but tool output never shrinks and BOARD.md never condenses. - Cause:
orch hook post-tool/pre-compactresolveorch.yamlthe same way every command does — outside a registered workshop (no resolvableorch.yaml) the hook silently returns and does nothing, by design (a context hook must never fail loudly and break the agent it's helping). - Fix: confirm
orch homeresolves a workspace from where the hook runs, and thatorch guard wire --claude(or the OpenCode plugin wire) actually installed it — theorch.yamlflag alone doesn't wire it in.
cursor-agent says a hook failed with a syntax error near &#
- Symptom: a worker running
cursor-agenton Windows has every tool blocked, and its log shows a hook dying withsyntax error near unexpected token '&'. - Cause: cursor-agent picks bash to evaluate its own (PowerShell-flavored)
hook wrapper when the process environment has a POSIX-looking
SHELL— which it inherits when the Chair itself ran under Git Bash (Claude Code →orch mcp→ worker). Orchemax stripsSHELL/MSYSTEM*from a dispatched worker's environment for exactly this reason; an olderorchbuild did not. - Fix: update
orch. If it recurs, confirm nothing else re-setsSHELLin the workspace or the agent's own config before it launches.
A worker closes "ok" but its log says "MCP server does not exist: orch"#
- Symptom: a dispatched worker's
.orch-agent.logshows the CLI itself complaining it has noorchMCP server (MCP server does not exist: orchororch MCP is not connected), yet the session still closes andverify_statusused to readguardrails: ok. - Cause: the CLI loaded only its machine-global MCP config and never
approved the worktree's own
.cursor/mcp.json/.mcp.json/.orch/mcp.json— every worker-side MCP tool (msg_send,verify_report,lock_acquire,code_snippet,search_shared_symbols) was unreachable for the whole session. For cursor-agent specifically:cursor-agent mcp listshows the project server stuck at "not loaded (needs approval)" in headless mode, because nobody is there to approve it. - Fix: update
orch— thecursorpreset now passes--approve-mcps, and verification now fails with reasonorch MCP unavailable in workerwhenever the log carries that marker, instead of reading "ok". If a different CLI still shows this, confirm it has a documented flag or workspace-config convention for auto-loading project MCP servers headless (copilot reads.mcp.jsonon its own; agy has no per-workspace MCP config at all — runorch guard wire --agy --scope user --allow-user-scopeonce to registerorchin its global one, which is what its reason line tells you — seeconfigure-agents.md).
orch cursor freezes on “MCP servers need to be approved”#
- Symptom: interactive Cursor shows Approve for the
orchMCP server, then hangs onApplying your selection...until you kill the terminal. - Cause: Cursor’s MCP approval whitelist (
mcp-approvals.json) hashes the project server entry. Orch rewrites.cursor/mcp.jsonwith a newORCH_SESSIONeach seat, so the hash misses and the TUI returns every launch. Without--approve-mcpson the interactive preset, that dialog is unavoidable — and applying it often freezes under the seat console. - Fix: update
orch(interactive default iscursor-agent --approve-mcps --trust). Or setagents.interactive.cursor/ORCH_AGENT_CMDthe same way. Field matrix for other CLIs’ allowlists: common seat tune-ups — vendor allowlists.
Cursor / Claude plan / Codex lost connectors after gateway connect#
- Symptom: after pasting
:8788/orch_gk_…into Cursor, Claude Code, or Codex, the seat asks for an API key, drops plan connectors, or gateway returns403on an OAuth bearer. - Cause: those seats default to account / plan login — model traffic stays on the vendor login. The gateway is only for API-key / BYO seats.
- Fix: restore the vendor login; set
agents.auth.<preset>: account(or leave unset). Do not point plan seats at the gateway. See common seat tune-ups — account / plan login.
orch usage shows zero right after a session#
- Symptom: a plan-billed seat (e.g. Claude Code on its own login) just
ran, but
orch usageshows no tokens for it. - Cause: there's no billing API for a plan login — usage for these seats
comes from scanning the harness's own transcript files under
~/.claude/projects/<slug>/*.jsonl, which can lag the live session. - Fix: re-run
orch usageafter the transcript is written — it scans transcripts on every invocation, so a second run is enough.