_generate_summary in context_compressor.py crashes with TypeError when any message in the summarized range has content: None.
Root cause
File: agent/context_compressor.py, lines 90-91
content = msg.get("content", "")
if len(content) > 2000:
dict.get("content", "") returns the default "" only when the key is missing. When the key exists with value None, it returns None. Calling len(None) raises TypeError.
The same None value also breaks the string concatenation on line 96:
content += f"\n[Tool calls: {', '.join(tool_names)}]"
How content becomes None
The OpenAI API returns content: null on assistant messages that only contain tool calls. The gateway builds conversation history at gateway/run.py, line 210:
{"role": m.get("role"), "content": m.get("content")}
m.get("content") returns None when the key is absent, so content: None enters the conversation history. When the conversation runs long enough to trigger context compression, these messages reach _generate_summary and crash it.
Reproduction
>>> msg = {"role": "assistant", "content": None, "tool_calls": []}
>>> content = msg.get("content", "")
>>> content
None
>>> len(content)
TypeError: object of type 'NoneType' has no len()
This affects any conversation that uses tool calls and runs long enough to trigger context compression.
Suggested fix
content = msg.get("content") or ""
This handles both missing keys and explicit None values.
_generate_summaryincontext_compressor.pycrashes withTypeErrorwhen any message in the summarized range hascontent: None.Root cause
File:
agent/context_compressor.py, lines 90-91dict.get("content", "")returns the default""only when the key is missing. When the key exists with valueNone, it returnsNone. Callinglen(None)raisesTypeError.The same
Nonevalue also breaks the string concatenation on line 96:How content becomes None
The OpenAI API returns
content: nullon assistant messages that only contain tool calls. The gateway builds conversation history atgateway/run.py, line 210:{"role": m.get("role"), "content": m.get("content")}m.get("content")returnsNonewhen the key is absent, socontent: Noneenters the conversation history. When the conversation runs long enough to trigger context compression, these messages reach_generate_summaryand crash it.Reproduction
This affects any conversation that uses tool calls and runs long enough to trigger context compression.
Suggested fix
This handles both missing keys and explicit
Nonevalues.