← Back to PRs

#11986: fix: drop empty assistant content blocks from error/aborted API responses

by cy69855522 open 2026-02-08 17:26 View on GitHub →
agents stale
## 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