From 33ab5cec825f6feaf5c75099b3002eff84c05962 Mon Sep 17 00:00:00 2001 From: teknium1 Date: Mon, 2 Mar 2026 02:23:53 -0800 Subject: [PATCH] fix: handle None message content across codebase (fixes #276) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OpenAI API returns content: null on assistant messages with tool calls. msg.get('content', '') returns None when the key exists with value None, causing TypeError on len(), string concatenation, and .strip() in downstream code paths. Fixed 4 locations that process conversation messages: - agent/auxiliary_client.py:84 — None passed to API calls - cli.py:1288 — crash on content[:200] and len(content) - run_agent.py:3444 — crash on None.strip() - honcho_integration/session.py:445 — 'None' rendered in transcript 13 other instances were verified safe (already protected, only process user/tool messages, or use the safe pattern). Pattern: msg.get('content', '') → msg.get('content') or '' Fixes #276 --- agent/auxiliary_client.py | 2 +- cli.py | 2 +- honcho_integration/session.py | 2 +- run_agent.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/agent/auxiliary_client.py b/agent/auxiliary_client.py index c2b3bbfa0..51db04f0b 100644 --- a/agent/auxiliary_client.py +++ b/agent/auxiliary_client.py @@ -81,7 +81,7 @@ class _CodexCompletionsAdapter: input_msgs: List[Dict[str, Any]] = [] for msg in messages: role = msg.get("role", "user") - content = msg.get("content", "") + content = msg.get("content") or "" if role == "system": instructions = content else: diff --git a/cli.py b/cli.py index bbd09e2b3..faa6586d1 100755 --- a/cli.py +++ b/cli.py @@ -1285,7 +1285,7 @@ class HermesCLI: for i, msg in enumerate(self.conversation_history, 1): role = msg.get("role", "unknown") - content = msg.get("content", "") + content = msg.get("content") or "" if role == "user": print(f"\n [You #{i}]") diff --git a/honcho_integration/session.py b/honcho_integration/session.py index 11e28b765..a384b429d 100644 --- a/honcho_integration/session.py +++ b/honcho_integration/session.py @@ -442,7 +442,7 @@ class HonchoSessionManager: for msg in messages: ts = msg.get("timestamp", "?") role = msg.get("role", "unknown") - content = msg.get("content", "") + content = msg.get("content") or "" lines.append(f"[{ts}] {role}: {content}") lines.append("") diff --git a/run_agent.py b/run_agent.py index 6cfcb1b8f..da491dde1 100644 --- a/run_agent.py +++ b/run_agent.py @@ -3441,7 +3441,7 @@ class AIAgent: self._codex_incomplete_retries += 1 interim_msg = self._build_assistant_message(assistant_message, finish_reason) - interim_has_content = bool(interim_msg.get("content", "").strip()) + interim_has_content = bool((interim_msg.get("content") or "").strip()) interim_has_reasoning = bool(interim_msg.get("reasoning", "").strip()) if isinstance(interim_msg.get("reasoning"), str) else False if interim_has_content or interim_has_reasoning: