Skip to content

bug(orchestration): Claude child prompt delivery fails on create and an immediate retry orphans a half-written prompt #854

Closed

Description

@Juliusolsson05

Expected

orchestration_create_agent with kind: "claude" and an initial prompt creates the child and delivers the prompt. If the composer isn't ready yet, it waits for readiness or retries on its own, as it does for Codex children.

Actual

This reproduced on two freshly created Claude children in the same parent session (2026-09-10). A Codex child created in parallel with a similar prompt started normally.

  1. create_agent (claude, ~4 KB multi-line prompt, cwd = a repo worktree) returned:
    {"ok":false,"error":"prompt_delivery_failed","message":"Claude session … prompt input is still warming (composer-unpainted)","retrySafe":true,"disposition":"retry-same-session","promptSubmitted":false}
  2. An immediate orchestration_send_prompt retry of the same prompt to that session, as the disposition says to do, returned:
    {"ok":false,"error":"prompt_delivery_failed","message":"Claude session … did not visibly absorb the prompt and its composer could not be recovered","retrySafe":false,"stage":"absorption","code":"absorption-timeout","disposition":"do-not-retry","promptWritten":true,"enterWritten":false,"promptSubmission":"uncertain"}
    orchestration_read_agent then showed messageCount: 0, promptSubmitted: false. The prompt bytes had been written without Enter, so the session had to be closed.
  3. A second fresh Claude child gave the same composer-unpainted result from create_agent. After a delay, send_prompt with a one-line prompt (pointing the agent at a file containing the full brief) succeeded.

Hypotheses (unconfirmed)

  • Timing: create_agent's readiness wait gives up before a Claude child's composer paints, and the retry-same-session disposition invites an immediate retry that hits the same not-ready window.
  • Paste folding: Claude's TUI folds large multi-line pastes into [Pasted text #N +M lines], so the absorption check can't see the text and times out after writing it (promptWritten: true, enterWritten: false). That leaves the orphaned-draft state bug(claude): an orphaned prompt write deadlocks the session as a permanent 'human draft' #679 fixed for another path.

Step 3 changed both variables (later and shorter), so this evidence doesn't separate the two.

Impact

Orchestrated multi-agent work with Claude children fails on the first attempt, and following the tool's own retry-same-session advice can leave an unrecoverable, half-written composer. The workaround is a short bootstrap prompt that points the child at a file.

Environment

macOS, Agent Code main at 48ea691, Claude child created in Dispatch via the built-in orchestration MCP.

Activity

  1. Juliusolsson05 commented on Sep 11, 2026

    @Juliusolsson05
    OwnerAuthor

    New data point (2026-09-10, PR #860 review run): orchestration_create_agent kind claude with a ONE-LINE prompt (~230 chars, no newlines) also failed with prompt_delivery_failed … composer-unpainted ("prompt input is still warming"), disposition retry-same-session. About 25–35 s later, after checking list_agents showed the session waiting with promptSubmitted:false, a single send_prompt with the same one-line text succeeded first try. A Codex child created in the same moment received its prompt on create. So prompt length/paste folding is not required to trigger it; it looks like create-time composer warm-up timing, and a delayed (not immediate) retry on the same session works.

  2. Juliusolsson05 commented on Sep 20, 2026

    @Juliusolsson05
    OwnerAuthor

    Evidence: 134 recorded delivery failures, 11 app runs, 2026-08-30 → 2026-09-20

    The hypotheses in this issue were unconfirmed because step 3 changed two variables at once. They don't have to stay unconfirmed — the app has been recording every one of these in the run journal (~/.config/agent-code/incidents/runs/*/incidents.jsonl, kind: orchestration.prompt_delivery_failed). Here is the whole corpus, grouped by the message the provider actually returned.

    create_agent bootstrap failures — 55 total

    n provider what the delivery said
    26 claude prompt input is blocked by claude.trust-dialog
    21 claude prompt input is still warming (composer-unpainted)
    5 codex was not ready for prompt delivery (timeout)
    3 claude did not record prompt acceptance
    2 claude did not visibly absorb the prompt
    2 claude did not visibly absorb the prompt and its composer could not be recovered
    2 codex was not ready for prompt delivery (blocked)
    1 claude did not visibly absorb … the draft was cleared
    1 codex was not ready for prompt delivery (terminal)

    send_prompt failures — 79 total, dominated by Codex not-ready timeouts (38), Claude human-draft (10), Claude acceptance (9) and Claude absorption (7+2+1).

    What this settles

    1. The dominant bootstrap failure is not paste folding. Only 5 of 55 bootstrap failures reached the absorption stage at all. Hypothesis 2 in this issue — Claude folding a big paste into [Pasted text #N +M lines] so the absorption check can't see it — is already handled: pasteConfirm.ts counts placeholders (PASTE_PLACEHOLDER_RE) as absorption evidence, and isPasteLike routes anything over 100 chars or with a newline through that protocol. The 4 KB prompt in this report is not what made it fail.

    2. 47 of 55 bootstrap failures (85%) are "not ready YET" states that resolve on their own. 26 are the trust dialog — a first-launch prompt in a directory Claude has not been trusted for, which an orchestration child in a fresh worktree hits every time — and 21 are a composer that had not painted inside the 12 s readiness budget. Neither is a broken session. In both, the child is fine and the prompt is simply early.

    That is what makes the retry-same-session disposition so unhelpful here: it invites an immediate retry into the same window, and the second attempt is what reaches the absorption stage and can leave prompt bytes without Enter — the orphaned draft this issue's step 2 describes.

    3. It is not rare and it is not new. 11 separate app runs over three weeks. The most recent is today.

    Shape of the fix this points to

    The bootstrap prompt should not be an all-or-nothing synchronous delivery inside create_agent's readiness budget. For a child that is warming or blocked, the prompt should be held and delivered when the gate reports ready — the machinery already exists (awaitReadyForPrompt is event-driven on prompt-gate, and claude.trust-dialog is already surfaced as a condition the user can answer), and orchestrationBootstrapPromptDelivered already records whether it went.

    That covers 47 of the 55 recorded failures with one change, and it removes the retry that produces the orphaned draft. A longer readiness budget would not: the trust dialog does not clear on a timer at all.

    Numbers above are reproducible from the run journal; nothing here is inferred from reading the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions