TaskOutput returns truncated raw JSONL transcript instead of subagent's final answer
Summary
When retrieving results from background subagents via TaskOutput, the parent context receives ~30KB of raw JSONL session transcript fragments instead of the subagent's actual final answer. This defeats the purpose of using subagents to manage context window size.
Synchronous Task calls work correctly — they return only the subagent's clean final message. The bug is specific to the run_in_background: true → TaskOutput retrieval path.
Reproduction
- Launch multiple subagents with
run_in_background: true - Wait for them to complete
- Retrieve results with
TaskOutput - Observe that the returned content is truncated raw JSONL, not the subagent's final answer
Evidence from session analysis
Analyzed session file: bc08e837-08c0-4918-a721-91114d985238.jsonl
TaskOutput results (the bug)
All 4 TaskOutput retrievals show identical structure — exactly 30,156 chars every time:
| task_id | message.content (enters context) | task.output (full transcript) | Content starts with |
|---|---|---|---|
| a6ae3c7 | 30,156 chars | 219,265 chars | const·entry·of·entries)·{ (mid-code fragment) |
| a1988e0 | 30,156 chars | 104,129 chars | imestamp":"2026-02-15T22:25:21.797Z" (mid-JSON) |
| a727ec1 | 30,156 chars | 130,840 chars | ff6e78a18","isSidechain":true (mid-JSON) |
| a3abc92 | 30,156 chars | 172,442 chars | 7→\t\t\t\"SKILL.md\" (mid-file listing) |
The 30,156 chars break down as:
- 147 chars: XML status header (
<retrieval_status>success</retrieval_status>,<task_id>, etc.) - ~105 chars: Truncation marker (
[Truncated. Full output: /private/tmp/claude-502/.../tasks/<id>.output]) - 29,904 chars: The last ~30KB of the subagent's raw JSONL session transcript, starting mid-word
The 29,904 chars of trailing JSONL contain raw session log entries: tool_use/tool_result blocks, system prompts, diff output, cache token metadata, system reminders — not the subagent's final answer.
Synchronous Task results (working correctly, for comparison)
| agentId | message.content size | Content |
|---|---|---|
| a2f6f50 | 18,782 chars | Clean markdown report starting with ## Comprehensive Analysis... |
| a14aa70 | 980 chars | Clean report starting with ## Report\n\n**What I implemented:**... |
| af8a52b | 5,311 chars | Clean self-review starting with ## Self-Review Summary... |
| a6e4937 | 2,316 chars | Clean summary starting with All three spec compliance issues are fixed... |
These are well-formatted final answers — exactly what you'd expect.
Additional data issue: task.output and task.result are identical
In the JSONL log, each TaskOutput entry stores the full transcript in both toolUseResult.task.output and toolUseResult.task.result — identical content, doubling the on-disk storage:
| task_id | task.output | task.result | Identical? |
|---|---|---|---|
| a6ae3c7 | 219,265 chars | 219,265 chars | Yes |
| a1988e0 | 104,129 chars | 104,129 chars | Yes |
| a727ec1 | 130,840 chars | 130,840 chars | Yes |
| a3abc92 | 172,442 chars | 172,442 chars | Yes |
Expected behavior
TaskOutput should return the subagent's final assistant message to the parent context — the same clean, well-formatted answer that synchronous Task calls return. The full JSONL transcript can remain in task.output for debugging, but it should not be what enters the parent's context window.
Impact
- Each background subagent adds ~30KB of useless JSONL fragments to the parent context
- 4 async subagents = ~120KB of garbage in context that the model must parse through
- The subagent's actual useful answer (typically a few hundred chars to a few KB) is lost — it may or may not appear within the trailing 30KB chunk
- This undermines the primary value proposition of background subagents: keeping the parent context clean
Environment
- Claude Code CLI
- macOS (Darwin 24.6.0)
- Observed on February 15, 2026
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗