Repository navigation
Autopilot repeatedly retries write_agent for completed non-resumable agent with conflicting selectors #5210
Description
Describe the bug
When a background agent has completed as blocked and is non-resumable, the coordinator can repeatedly call write_agent instead of replacing it. In the observed failure, the model also supplied all three mutually exclusive selectors (agent_id, agent_ids, and scope) on every retry, so each call failed schema validation before the runtime could report the target agent's terminal lifecycle state.
The result was a long Autopilot loop displaying repeated Write <agent-id> calls with no recovery.
Observed sequence:
-
A background general-purpose agent was launched successfully.
-
The agent completed with a blocked result because it started from the wrong working directory. Its launch metadata reported
resumable: false. -
The coordinator attempted to steer/resume the completed agent repeatedly.
-
Every generated
write_agentcall contained all three selectors:{ "agent_id": "<agent-id>", "agent_ids": ["<agent-id>"], "scope": "children", "message": "Resume..." } -
The tool returned:
Provide exactly one of "agent_id", "agent_ids", or "scope" -
Autopilot retried the same malformed operation many times instead of inspecting lifecycle state and starting a replacement.
The old agent had no durable resumable session. Starting a fresh agent with the original objective, preserved worktree, and absolute project root recovered the work.
Affected version
1.0.100
Steps to reproduce the behavior
- Start a background agent with
mode: "background". - Have the agent finish with a blocked result and a terminal/non-resumable lifecycle state.
- Ask the main agent to resume or steer that completed agent.
- Observe the main model call
write_agentrepeatedly. - In the failing case, inspect the tool calls and observe that
agent_id,agent_ids, andscopeare all populated. - Observe every call fail with
Provide exactly one of "agent_id", "agent_ids", or "scope". - Observe Autopilot continue retrying the dead agent instead of launching a replacement.
Expected behavior
The tool and orchestrator should defend against both failure modes:
-
The generated
write_agentcall should contain exactly one selector. -
When the target is completed, failed, cancelled, missing, or non-resumable, the tool should return a structured actionable result, for example:
agent_not_resumable: Agent <id> is completed/blocked and cannot accept messages. Do not retry write_agent. Start a new task agent using the original objective and preserved context. -
Autopilot should treat that response as terminal for the old agent ID and automatically start a fresh replacement with the original objective and durable context.
-
After an invalid-selector response, the coordinator should retry at most once with only
agent_id, not loop indefinitely.
Additional context
- OS: macOS, arm64
- Interface: interactive TUI, Autopilot
- Agent: background general-purpose agent
- Model:
gpt-6.1-sol, accessed through a custom OpenAI-compatible gateway - API subtype: OpenAI Responses (
/v1/responses) - The replacement-agent workaround was successful when explicitly given the original objective, absolute worktree/project root, approved plan, constraints, and known progress.
Related open issues:
- CLI: follow-up to an idle background agent is delayed by minutes to hours while its status shows "running" #5143 — follow-ups to idle agents can be delayed; its documented workaround is starting a fresh agent.
- write_agent may block until the target background agent starts actively processing, causing new user input to queue #4101 —
write_agentmay block while waking an idle agent. - Background sub-agent stream failures end the turn without a failure status #4911 — background subagent stream failures can end without a failure status.
- Background agent completion retention #2595 — completed agents can disappear and become unrecoverable.
Those issues cover adjacent delivery, status, and retention failures, but I could not find one covering the exact combination of malformed selector retries plus failure to replace a terminal/non-resumable agent.
Suggested lifecycle handling:
- Permit
write_agentonly for agents currently reported asrunningoridle. - Reject terminal/non-resumable agents with a dedicated error code and replacement guidance.
- Persist enough final metadata/result for the coordinator to seed a replacement safely.
Activity