fix(trim_messages): handle list-type content on system messages

trim_messages() built the trimmed system prompt by doing
system_message += message["content"] for every system-role message,
assuming content is always a plain string. OpenAI/Anthropic-style
multi-part content (content: [{"type": "text", "text": "..."}])
is a valid, common message shape, and this crashed with:

  TypeError: can only concatenate str (not "list") to str

Handle both shapes: strings are appended as before; list content is
walked and any {"type": "text"} parts' text is appended, matching
how other content-part handling in the codebase treats this format.

Found via real-world load testing of a Frappe-based app hitting this
frequently under concurrent load with varied prompt shapes (888-1300+
occurrences in a single 50-minute test window).

Verified: a system message with list-type content no longer crashes
trim_messages() and produces the expected joined system_message; a
plain string-content system message is unaffected (no regression).
This commit is contained in:
Safwan Erooth 2026-07-24 12:19:49 +04:00
parent b9b27c2beb
commit a45c874d20

View file

@ -6806,7 +6806,13 @@ def trim_messages(
for message in messages:
if message["role"] == "system":
system_message += "\n" if system_message else ""
system_message += message["content"]
content = message.get("content", "")
if isinstance(content, str):
system_message += content
elif isinstance(content, list):
for part in content:
if isinstance(part, dict) and part.get("type") == "text":
system_message += part.get("text", "")
## Handle Tool Call ## - check if last message is a tool response, return as is - https://github.com/BerriAI/litellm/issues/4931
tool_messages = []