Skip to content

[Bug] Subagent announce extracts toolResult instead of final assistant text when last turn includes large tool output #81690

Description

@Umarchen

Bug type

Race condition / announce result extraction

Beta release blocker

No

Summary

When a subagent's final turn includes a large tool result (>16KB, e.g. a curl command fetching OpenCode session JSON), the subagent_announce mechanism delivers the toolResult content to the parent session instead of the subagent's final assistant text (the structured completion report).

The parent agent receives a truncated toolResult JSON and never sees the subagent's actual completion summary.

Steps to reproduce

  1. Spawn a subagent (e.g. devops-agent) that performs multiple tool calls in its final turn.
  2. The subagent's last tool call fetches large output (e.g. curl retrieving a 96KB OpenCode session JSON via exec).
  3. The subagent then outputs a short structured report as its final assistant text (e.g. 1KB summary with test results and deliverables).
  4. When the subagent completes, the parent receives a subagent_announce containing the truncated curl output, not the assistant report.

Expected behavior

The announce should deliver the subagent's final assistant text (the completion report), not the preceding toolResult.

Per the documented strategy: "Result — latest visible assistant reply text, otherwise sanitized latest tool/toolResult text" — the assistant text should take priority.

Actual behavior

The announce delivers the toolResult from the last tool call:

  • The 96KB curl output becomes the announce result
  • It gets truncated at the 16KB DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS limit
  • The actual assistant report (1KB structured summary) is never delivered to the parent

Observed comparison

Subagent Last tool output size Parent receives Correct?
BA (small toolResult) ~100 bytes Assistant report ✅ Yes
DevOps speed test (small toolResult) ~500 bytes Assistant report ✅ Yes
DevOps formal task (96KB curl) ~96KB Truncated toolResult ❌ No

Root cause analysis

In subagent-session-cleanup-BCiiUQZB.js, readSubagentOutput() calls chat.history to read the child session messages, then summarizeSubagentOutputHistory() walks the message list to extract:

  1. latestSilentText (NO_REPLY)
  2. latestAssistantText (assistant text)
  3. Partial progress (timeout fallback)
  4. latestRawText (includes toolResult — final fallback)

The issue appears to be a race condition: when the framework calls chat.history immediately after the subagent completes, the final assistant message may not yet be fully persisted to the transcript. The API returns the large toolResult as the latest visible content, and selectSubagentOutputText falls through to latestRawText.

The readLatestSubagentOutputWithRetry fallback also fails to recover the final assistant text.

Small toolResults don't trigger visible issues because even when the race occurs, the toolResult content fits within the 16KB limit and the parent can still see the full context. The problem only manifests when toolResults are large enough to be truncated.

Environment

  • OpenClaw version: 2026.5.x
  • Reproduction: Any subagent whose final turn includes a tool call producing >16KB output
  • Framework files: subagent-session-cleanup-BCiiUQZB.js (extract logic), compaction-BxhK_yKO.js (16KB truncation)

Suggested fix

  1. Increase retry delay/window in readLatestSubagentOutputWithRetry to wait for final assistant text to persist before falling back to toolResult.
  2. Or: After chat.history returns, check if the last assistant message has tool calls without a subsequent assistant text reply — if so, delay and retry before using latestRawText.
  3. Or: Add a small grace period (e.g. 500ms–1s) between subagent completion and announce delivery to allow transcript persistence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions