fix: Skip empty AI messages in output_langchain to prevent API rejection
Empty or whitespace-only AI messages cause API validation errors with strict providers (OpenAI, Z.ai, GLM): "Assistant messages must have either content or tool_calls" This is a companion fix to PR #927 (response.py KeyError fix). When that fix returns an empty string instead of crashing, the empty string can become an empty AIMessage that fails API validation. Changes: - Pre-compute content before creating message objects - Skip AI messages where content is None, empty, or whitespace-only - Human messages are not filtered (they can be empty per spec) Tested on 4 production A0 instances.
Frank Hurt committed
Feb 1, 2026 at 03:26 UTC
a129a576d759b75998103e77f9465fc9342ce56d
1 file changed
+7
-4
python/helpers/history.py
+7
-4
@@ -519,12 +519,15 @@ def group_messages_abab(messages: list[BaseMessage]) -> list[BaseMessage]:
519
def output_langchain(messages: list[OutputMessage]):
520
result = []
521
for m in messages:
522
+ content = _output_content_langchain(content=m["content"])
523
+ # Skip AI messages with empty/whitespace-only content
524
+ # (API spec requires assistant messages to have content or tool_calls)
525
if m["ai"]:
523
- # result.append(AIMessage(content=serialize_content(m["content"])))
524
- result.append(AIMessage(_output_content_langchain(content=m["content"]))) # type: ignore
526
+ if not content or (isinstance(content, str) and not content.strip()):
527
+ continue
528
+ result.append(AIMessage(content)) # type: ignore
529
else:
526
- # result.append(HumanMessage(content=serialize_content(m["content"])))
527
- result.append(HumanMessage(_output_content_langchain(content=m["content"]))) # type: ignore
530
+ result.append(HumanMessage(content)) # type: ignore
531
# ensure message type alternation
532
result = group_messages_abab(result)
533
return result