#11986: fix: drop empty assistant content blocks from error/aborted API responses
agents
stale
Cluster:
Error Handling in Agent Tools
## Problem
When an API request fails before producing any output, OpenClaw writes an assistant message with `content: []` (empty array) into the session transcript `.jsonl` file. On subsequent requests, this empty-content assistant message is included in the conversation history sent to the API.
The Anthropic Messages API rejects assistant messages with empty content arrays, returning:
```
HTTP 400: api_error: Improperly formed request. (reason: None)
```
This creates a **death spiral**:
1. Initial API error → empty `content: []` assistant message written to session
2. Next user message → history includes the empty assistant message → API rejects → another empty assistant message written
3. Repeat forever — the session is permanently broken
Closes #11963
## Fix
Strip empty-content assistant messages in both transcript repair functions:
- **`repairToolCallInputs`**: drops any assistant message with `content: []` (regardless of stopReason)
- **`repairToolUseResultPairing`**: drops error/aborted assistant messages with empty content instead of passing them through unchanged
This fixes existing corrupted sessions (repair runs on history load) and prevents future poisoning.
## Evidence from session transcript
```json
{"type":"message","message":{"role":"assistant","content":[],"stopReason":"error","errorMessage":"400 {\"type\":\"error\",\"error\":{\"type\":\"api_error\",\"message\":\"Improperly formed request. (reason: None)\"}}"}}
```
Multiple consecutive user messages after this all fail with the same 400 error, confirming the death spiral.
## Testing
Added tests covering:
- Dropping errored assistant messages with empty content
- Dropping aborted assistant messages with empty content
- Keeping errored assistant messages that have non-empty content (partial responses)
- Handling multiple consecutive empty errored messages (the exact death spiral scenario)
- Dropping empty content in `repairToolCallInputs` (with and without stopReason)
Most Similar PRs
#9416: fix: drop errored/aborted assistant tool pairs in transcript repair
by xandorklein · 2026-02-05
73.1%
#15050: fix: transcript corruption resilience — strip aborted tool_use bloc...
by yashchitneni · 2026-02-12
68.9%
#14328: fix: strip incomplete tool_use blocks from errored/aborted messages...
by Kropiunig · 2026-02-12
68.5%
#16966: fix: strip tool_use blocks from aborted/errored assistant messages
by StressTestor · 2026-02-15
67.9%
#20538: fix: handle orphaned tool_result errors gracefully instead of leaki...
by echoVic · 2026-02-19
67.9%
#22465: fix: preserve session history after API error (400/503) in mid-conv...
by hhy5562877 · 2026-02-21
66.7%
#3880: fix: drop assistant messages with stopReason 'error' to avoid orpha...
by SalimBinYousuf1 · 2026-01-29
66.4%
#4844: fix(agents): skip error/aborted assistant messages in transcript re...
by lailoo · 2026-01-30
65.8%
#13062: fix: remove orphaned tool_result blocks from user message content d...
by trevorgordon981 · 2026-02-10
65.7%
#15509: fix(session): drop tool_use blocks with empty or missing name
by aldoeliacim · 2026-02-13
65.7%