feat: Add max_return_size parameter to Task tool for task-notification truncation

Resolved 💬 3 comments Opened Feb 21, 2026 by Caylub Closed Feb 25, 2026

Problem

When a background agent (launched via the Task tool with run_in_background: true) completes, its full result is injected into the orchestrator's conversation as a <task-notification> message. There is no mechanism to:

  • Limit the size of this notification
  • Redirect it to a file instead of inline context
  • Auto-summarize it before injection
  • Suppress it entirely from the orchestrator's perspective

This means the orchestrator has zero control over how much context returning agents consume. The result size is entirely determined by the subagent's verbosity, and even well-prompted agents can return unexpectedly large payloads.

Real-World Impact

Incident: 36-agent orchestration session

I ran an orchestration session that launched 36 background agents in waves (extraction → synthesis → assembly). Despite explicit prompt instructions telling every agent to return only "DONE: /path/to/output.md" (15 words max), the <task-notification> payloads still consumed significant context because:

  1. Each notification includes framing/metadata beyond just the agent's return value
  2. Agents that hit errors returned verbose diagnostics instead of the terse success message
  3. With 36 agents, even small per-notification overhead compounds

The workaround required 6 defensive rules copy-pasted into every orchestrator prompt:

## CONTEXT PROTECTION (MANDATORY)
1. Never call TaskOutput — check file existence instead
2. Agent returns <= 15 words — just "DONE: /path/to/output.md"
3. Don't acknowledge task notifications — stay silent, check counts when ready
4. Don't read agent output files — the synthesis agent reads them
5. Check completion via file existence — `ls $DIR/logs/agent-*.done | wc -l`
6. Monitor agents via heartbeat staleness — blocking monitor script

This works but is fragile — it relies on prompt discipline from both the orchestrator and every subagent. One verbose agent breaks the whole pattern.

Incident: 7-agent audit (from #23463)

A user spawned 7 audit subagents that each returned 15K–37K chars. The combined 150K chars of agent output caused an unrecoverable "Prompt is too long" crash with no graceful degradation. The session was permanently dead.

Proposed Solutions

In order of preference:

1. max_return_size parameter on the Task tool

Add an optional parameter that truncates the agent's return value before injecting it as a <task-notification>:

{
  "name": "Task",
  "parameters": {
    "prompt": "Audit the auth module...",
    "subagent_type": "general-purpose",
    "run_in_background": true,
    "max_return_size": 200
  }
}

If the agent's result exceeds max_return_size tokens, truncate it and append [truncated — full result in output_file]. The full result would still be available via the output_file path returned at launch time.

Why this is best: It gives the orchestrator per-task control at launch time, requires no global config, and works with the existing output_file mechanism for full results.

2. task_notification_mode setting

A global or per-task setting controlling how notifications are delivered:

| Mode | Behavior |
|------|----------|
| full | Current behavior — inject entire result (default) |
| summary | Auto-summarize the result before injection (using a fast model) |
| file | Write result to file, inject only the file path |
| silent | No notification at all — orchestrator checks output_file manually |

{
  "settings": {
    "task_notification_mode": "file"
  }
}

3. task_notification_max_tokens global setting

A simpler version of #1 as a global setting:

{
  "settings": {
    "task_notification_max_tokens": 500
  }
}

All task notifications would be truncated to this limit, with full results available via output_file.

4. Allow hooks to modify/truncate tool results

Extend PostToolUse or Notification hooks to support result modification (not just gate/allow behavior). A hook could rewrite a task-notification to just a file path before it enters context.

Current Workarounds

All current workarounds require prompt engineering discipline:

  1. Terse return instructions: Tell agents to return only "DONE: /path" — but agents don't always comply, especially on errors
  2. File-based communication: Agents write to files, orchestrator reads files — but notifications still arrive and consume context
  3. Never call TaskOutput: Avoid pulling full results into context — but notifications still inject automatically
  4. Defensive acknowledgment rules: Tell orchestrator to ignore notifications — burns a turn but doesn't prevent context consumption

These are all workarounds for the missing feature: the ability to control notification payload size at the platform level.

Reproduction Steps

  1. Launch 6+ background agents via the Task tool, each performing substantive work (file reads, web searches, code analysis)
  2. Do not set any return size limit (none exists)
  3. Observe that each agent's full result is injected as a <task-notification> into the orchestrator's context
  4. With enough agents or verbose enough results, the orchestrator's context fills up, triggering unwanted compaction or (in extreme cases) an unrecoverable crash

Related Issues

  • #23463 — Subagent results silently overflow context, causing unrecoverable session crash (bug report describing the same root cause)
  • #22703 — Batch background task notifications when Claude is idle (complementary — batching helps but doesn't solve size)
  • #22702 — Allow suppressing background task notifications via Notification hook (partial solution via hooks)
  • #20920 — False user confirmation from task notification events (task notifications are injected as user content)
  • #21700 — Background task killed notifications cause assistant context confusion

---

🤖 Generated with Claude Code

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗