hermes - ✅(Solved) Fix [Bug]: Assistant messages with empty content cause HTTP 400 on Anthropic-compatible proxies [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#11906Fetched 2026-04-18 05:58:19
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
0
Timeline (top)
referenced ×4cross-referenced ×2commented ×1labeled ×1

Error Message

Additional Logs / Traceback (optional)

Root Cause

Root Cause Analysis (optional)

Fix Action

Fixed

PR fix notes

PR #11924: fix: preserve None content on tool-call-only assistant messages (#11906)

Description (problem / solution / changelog)

Problem

Empty assistant content (None) gets normalized to empty string '', which causes HTTP 400 on Anthropic-compatible proxies ('text content blocks must be non-empty'). This happens when the model returns a tool-call-only response.

Fix

Three-layer normalization to prevent empty text blocks:

  1. run_agent.py (storage): Normalize empty string to None when storing assistant messages
  2. run_agent.py (API prep): Strip empty assistant content before sending to API (2 locations)
  3. anthropic_adapter.py: Normalize in Anthropic message conversion as defensive guard

Tests

  • New test files covering empty content round-trips and Anthropic adapter behavior

Fixes #11906

Changed files

  • agent/anthropic_adapter.py (modified, +5/-1)
  • environments/agent_loop.py (modified, +2/-2)
  • run_agent.py (modified, +20/-3)
  • tests/environments/test_agent_loop_none_content.py (added, +84/-0)
  • tests/run_agent/test_run_agent.py (modified, +2/-1)
  • tests/test_empty_assistant_content.py (added, +162/-0)

Code Example

HTTP 400: "messages: text content blocks must be non-empty"

---

*

---
RAW_BUFFERClick to expand / collapse

Bug Description

When using an OpenAI-compatible proxy that forwards to Anthropic (e.g. claude-code-router, one-api), the agent intermittently fails with:

HTTP 400: "messages: text content blocks must be non-empty"

Steps to Reproduce

  1. Configure hermes-agent to use an OpenAI-compatible proxy that forwards to Anthropic (e.g. base_url: http://localhost:3001/v1)
  2. Start a conversation that triggers tool calls
  3. After the model returns a tool-call-only response (content is None), the empty string gets stored in history
  4. On the next API round-trip, the proxy rejects the empty text block → HTTP 400

Expected Behavior

Empty assistant content should be normalized to None instead of "", preventing the proxy from generating empty text blocks.

Actual Behavior

assistant_message.content = None → normalized to "" → stored in history → proxy translates to {"type": "text", "text": ""} → Anthropic rejects with 400.

Affected Component

CLI (interactive chat)

Messaging Platform (if gateway-related)

No response

Debug Report

*

Operating System

macos

Python Version

3.12.11

Hermes Version

Hermes Agent v0.10.0 (2026.4.16)

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

No response

Proposed Fix (optional)

No response

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

extent analysis

TL;DR

The issue can be fixed by normalizing empty assistant content to None instead of an empty string, preventing the proxy from generating empty text blocks.

Guidance

  • Verify that the assistant_message.content is being normalized to an empty string instead of None when the model returns a tool-call-only response.
  • Check the code that handles tool-call-only responses to ensure it correctly sets assistant_message.content to None.
  • Update the code to normalize empty assistant content to None instead of an empty string, for example by using a conditional statement to check if the content is empty before storing it in history.
  • Test the updated code with the OpenAI-compatible proxy to ensure it no longer generates empty text blocks and receives a 400 error.

Example

if assistant_message.content is None or assistant_message.content == "":
    assistant_message.content = None

Notes

This fix assumes that the issue is caused by the normalization of empty assistant content to an empty string. If the issue persists after applying this fix, further debugging may be necessary to identify the root cause.

Recommendation

Apply the workaround by normalizing empty assistant content to None instead of an empty string, as this should prevent the proxy from generating empty text blocks and fix the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug]: Assistant messages with empty content cause HTTP 400 on Anthropic-compatible proxies [1 pull requests, 1 comments, 2 participants]