Skip to content

[Bug]: Subagent completion silently dropped when announce steers into a requester run that ends before processing it #92433

Description

@aoclaw-glitch

Summary

When a subagent completes while its requester's run is still active, maybeSteerSubagentAnnounce (src/agents/subagent-announce-delivery.ts) enqueues the completion into the active run and returns status: "steered" as soon as queueOutcome.queued is true. waitForTranscriptCommit: true guarantees the message is written to the transcript, not that the run processes it. If the requester run ends in the window between enqueue and consumption, the completion sits in the transcript as a trailing user message forever: the run row gets completion_announced_at set, announce_retry_count stays null, no error is recorded anywhere, and no follow-up turn ever fires. The work dies silently.

Observed instance (2026-06-12, OpenClaw 2026.6.6 stable, macOS)

  • Requester turn (agent main, CLI-invoked): sessions_spawn accepted at 11:24:08Z, child agent:qa:subagent:7e67b290-…; requester called sessions_yield at 11:24:35.576Z.
  • Child completed at 11:24:33.1Z (ended_reason: subagent-complete, outcome ok).
  • Announce steered the [Internal task completion event] into the requester transcript at 11:24:35.644Z — 70 ms after the yield; the run's end marker follows at 11:24:36.013Z. No assistant entry ever follows it.
  • subagent_runs row: completion_announced_at = 1781263475645, announce_retry_count = NULL, last_announce_delivery_error = NULL, pending_final_delivery = 0 — i.e. the runtime believes delivery succeeded.

Identical orchestration on the same host where the child completed after the requester run fully ended took the direct path and worked (fresh completion agent turn fired ~30 s later). The failure is purely the enqueue-vs-run-teardown race, which makes it intermittent and very hard for operators to notice — there is no log line, no error, and the announce bookkeeping says delivered.

Expected

Either of:

  1. Steer delivery should only count as delivered once the run consumes the queued message; if the run ends with the completion still queued, fall back to the direct path (fresh completion agent turn) like the inactive-requester case already does, or
  2. Run teardown should flush queued internal completion events into a new turn instead of orphaning them in the transcript.

Impact

Multi-agent orchestration loses completions nondeterministically whenever a fast child finishes inside its requester's spawn turn — the requester yields 'waiting for completion' and never hears back. We are mitigating with a transcript sweep that detects trailing [Internal task completion event] entries with no assistant turn after them, but the race belongs upstream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions