Operating system
macOS
Orca version
1.4.177
Details
Short summary:
orca orchestration worker-start --worktree new-child --agent <x> writes the task prompt into the agent's PTY before the freshly launched agent TUI can accept a submit. The prompt lands in the composer but is never submitted, so the worker sits idle forever holding a fully typed prompt. The call returns ok: true with state: "ready" and stage: "input_accepted", so the coordinator believes the work started.
This is the same root cause as #13439, but it is not the same case, and the fix suggested there cannot be applied here:
What happened?
Two workers were started ten seconds apart, each into a new child worktree, on a repo whose setup hook runs a package install:
04:38:31 orca orchestration worker-start --task <A> --worktree new-child --name <a> --agent claude --model opus --setup run
04:38:42 orca orchestration worker-start --task <B> --worktree new-child --name <b> --agent claude --model opus --setup run
Both returned success:
{ "state": "ready", "stage": "input_accepted", "timeoutMs": 60000,
"setup": { "state": "running", "startupPolicy": "start-immediately" },
"effects": [ { "kind": "worktree", "action": "created_child" },
{ "kind": "terminal", "role": "agent", "action": "reused_agent_terminal" } ] }
Both agents then sat at Context 0% with the entire prompt visible in the composer, unsubmitted. worker-show reported status: dispatched, state: ready, last_heartbeat_at: null for both. Nothing was lost or truncated — each worktree's agent session file shows the complete Orca preamble plus the task spec as a single user message. Only the submit was missing.
Sending one byte to each agent terminal started them immediately:
orca terminal send --terminal <agentHandle> --text "" --enter
Evidence that this is a startup race, not a size or content problem
-
The sessions began exactly when the manual Enter was sent, roughly 4.5 minutes after dispatch:
| worker |
dispatched_at |
first message in agent session |
gap |
| A |
04:38:32 |
04:43:02.839 |
4m 30s |
| B |
04:38:42 |
04:43:38.053 |
4m 56s |
-
dispatched_at is one second after the command was issued, so no readiness wait happened at all. An agent CLI cannot boot, load MCP servers and skills, and render a composer in one second.
-
Prompt size is not the variable. Scanning every Orca-dispatched worker session on this machine (82 sessions, identified by the injected preamble) shows prompts up to 12,635 characters / 217 lines that dispatched fine. The two failures were 8,363 and 9,998 characters, mid-range.
-
Natural experiment across those 82 dispatches: worker-start --worktree new-child --agent was used exactly twice — both in this incident, both failed. Every successful dispatch in the history used an explicit readiness gate:
orca terminal create ... --command 'claude --model opus'
orca terminal wait --terminal <handle> --for tui-idle --timeout-ms 60000
orca orchestration dispatch --task <t> --to <handle> --inject
Prior worker-start uses were always bound to an already-idle existing terminal via --terminal <handle>, never to a newly created agent.
-
--model opus is not implicated: prior successful runs also launched claude --model opus, just behind the readiness gate.
Concurrent setup likely worsens the race but is not the mechanism. With --setup run and startupPolicy: start-immediately, setup ran in its own terminal and finished at 04:38:58 (A) and 04:39:25 (B), both after the injection, competing for CPU during agent boot.
How can we reproduce it?
- Use a repo with a setup hook that takes tens of seconds (for example a package install) and an agent whose startup loads MCP servers.
orca orchestration run-create --objective "..." then orca orchestration task-create --spec "...".
orca orchestration worker-start --task <id> --worktree new-child --name <n> --agent claude --model opus --setup run --json.
- Observe the receipt says
state: ready, stage: input_accepted.
orca orchestration worker-read --dispatch <id> reports fallbackReason: "transcript_missing", and the terminal shows the whole prompt in the composer at Context 0%. No heartbeat ever arrives.
Suggested fix
- Gate readiness inside
worker-start when it launches a new agent: wait for tui-idle (or the agent's own session/turn-start event) before injecting, and then send the prompt and the submit together.
- Fix the receipt semantics.
stage: "input_accepted" currently means "bytes were written to the PTY", but the guide presents ready as the signal to proceed. Either report a distinct stage for "submitted and a turn started", or do not settle the call as success until a turn is observed.
- On timeout, keep the prompt pending and report the failure rather than settling as
ready. If text is already in the composer, retry only the submit, never the body — resending would create two user turns.
- Until 1–3 land, either add a
--wait-for-tui-idle style flag to worker-start, or change the guide's Preferred Supervised Worker Loop to the split form below, since the currently documented one-call form has no way to avoid the race.
Workaround
Split the composed call so the readiness gate can be inserted, and never trust input_accepted alone:
orca worktree create --name <n> --parent-worktree active --agent claude --model opus --setup run
orca terminal wait --terminal <agentHandle> --for tui-idle --timeout-ms 120000
orca orchestration worker-start --task <id> --terminal <agentHandle>
To verify a worker actually started, orca orchestration worker-read --dispatch <id> should report a real transcript (fallbackReason: null). transcript_missing plus Context 0% means the prompt is loaded but never ran.
Operating system
macOS
Orca version
1.4.177
Details
Short summary:
orca orchestration worker-start --worktree new-child --agent <x>writes the task prompt into the agent's PTY before the freshly launched agent TUI can accept a submit. The prompt lands in the composer but is never submitted, so the worker sits idle forever holding a fully typed prompt. The call returnsok: truewithstate: "ready"andstage: "input_accepted", so the coordinator believes the work started.This is the same root cause as #13439, but it is not the same case, and the fix suggested there cannot be applied here:
terminal create→terminal wait --for tui-idle→terminal sendyourself. The composedworker-start --worktree new-child --agentpath exposes no seam to insert that wait. There is no--wait-for-tui-idleflag, and the worktree, the agent launch, and the dispatch all happen inside one call.What happened?
Two workers were started ten seconds apart, each into a new child worktree, on a repo whose setup hook runs a package install:
Both returned success:
{ "state": "ready", "stage": "input_accepted", "timeoutMs": 60000, "setup": { "state": "running", "startupPolicy": "start-immediately" }, "effects": [ { "kind": "worktree", "action": "created_child" }, { "kind": "terminal", "role": "agent", "action": "reused_agent_terminal" } ] }Both agents then sat at
Context 0%with the entire prompt visible in the composer, unsubmitted.worker-showreportedstatus: dispatched,state: ready,last_heartbeat_at: nullfor both. Nothing was lost or truncated — each worktree's agent session file shows the complete Orca preamble plus the task spec as a single user message. Only the submit was missing.Sending one byte to each agent terminal started them immediately:
Evidence that this is a startup race, not a size or content problem
The sessions began exactly when the manual Enter was sent, roughly 4.5 minutes after dispatch:
dispatched_atdispatched_atis one second after the command was issued, so no readiness wait happened at all. An agent CLI cannot boot, load MCP servers and skills, and render a composer in one second.Prompt size is not the variable. Scanning every Orca-dispatched worker session on this machine (82 sessions, identified by the injected preamble) shows prompts up to 12,635 characters / 217 lines that dispatched fine. The two failures were 8,363 and 9,998 characters, mid-range.
Natural experiment across those 82 dispatches:
worker-start --worktree new-child --agentwas used exactly twice — both in this incident, both failed. Every successful dispatch in the history used an explicit readiness gate:Prior
worker-startuses were always bound to an already-idle existing terminal via--terminal <handle>, never to a newly created agent.--model opusis not implicated: prior successful runs also launchedclaude --model opus, just behind the readiness gate.Concurrent setup likely worsens the race but is not the mechanism. With
--setup runandstartupPolicy: start-immediately, setup ran in its own terminal and finished at 04:38:58 (A) and 04:39:25 (B), both after the injection, competing for CPU during agent boot.How can we reproduce it?
orca orchestration run-create --objective "..."thenorca orchestration task-create --spec "...".orca orchestration worker-start --task <id> --worktree new-child --name <n> --agent claude --model opus --setup run --json.state: ready,stage: input_accepted.orca orchestration worker-read --dispatch <id>reportsfallbackReason: "transcript_missing", and the terminal shows the whole prompt in the composer atContext 0%. No heartbeat ever arrives.Suggested fix
worker-startwhen it launches a new agent: wait fortui-idle(or the agent's own session/turn-start event) before injecting, and then send the prompt and the submit together.stage: "input_accepted"currently means "bytes were written to the PTY", but the guide presentsreadyas the signal to proceed. Either report a distinct stage for "submitted and a turn started", or do not settle the call as success until a turn is observed.ready. If text is already in the composer, retry only the submit, never the body — resending would create two user turns.--wait-for-tui-idlestyle flag toworker-start, or change the guide's Preferred Supervised Worker Loop to the split form below, since the currently documented one-call form has no way to avoid the race.Workaround
Split the composed call so the readiness gate can be inserted, and never trust
input_acceptedalone:To verify a worker actually started,
orca orchestration worker-read --dispatch <id>should report a real transcript (fallbackReason: null).transcript_missingplusContext 0%means the prompt is loaded but never ran.