From e21213060574700224abf2c945e5ef6317e5859a Mon Sep 17 00:00:00 2001 From: lonexreb Date: Fri, 14 Aug 2026 22:45:32 -0500 Subject: [PATCH 1/3] [None][fix] validate reasoning item content in harmony responses input The harmony path of _parse_response_input indexed input_msg['content'] and asserted its length on unvalidated client input. Replaying a prior turn with a reasoning item that omits 'content' (the canonical shape) raised KeyError, and an empty list tripped a message-less assert that surfaced as an HTTP 400 with an empty error string. Mirror the non-harmony sibling: default missing content and raise a descriptive ValueError. Signed-off-by: lonexreb --- tensorrt_llm/serve/responses_utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tensorrt_llm/serve/responses_utils.py b/tensorrt_llm/serve/responses_utils.py index 13547a87a4fa..3b2acfe73625 100644 --- a/tensorrt_llm/serve/responses_utils.py +++ b/tensorrt_llm/serve/responses_utils.py @@ -160,8 +160,11 @@ def _parse_response_input( Author.new(Role.TOOL, f"functions.{call_response.name}"), input_msg["output"]) elif input_msg["type"] == "reasoning": - content = input_msg["content"] - assert len(content) == 1 + content = input_msg.get("content") or [] + if len(content) != 1: + raise ValueError( + "Input item of type 'reasoning' must have exactly one " + f"'content' element, got {len(content)}") msg = Message.from_role_and_content(Role.ASSISTANT, content[0]["text"]) elif input_msg["type"] == "function_call": msg = Message.from_role_and_content(Role.ASSISTANT, From f9893766cb588aaca2007713b80a2b2d2fcff13c Mon Sep 17 00:00:00 2001 From: lonexreb Date: Wed, 26 Aug 2026 00:01:51 -0700 Subject: [PATCH 2/3] [None][fix] ignore reasoning input items without content per review The Responses API allows reasoning items without 'content' (inferred from 'id' or recovered from 'encrypted_content', which is not implemented here). Instead of rejecting such items as invalid, follow the standard fallback behavior and skip them; the caller already filters None messages. Signed-off-by: lonexreb --- tensorrt_llm/serve/responses_utils.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tensorrt_llm/serve/responses_utils.py b/tensorrt_llm/serve/responses_utils.py index 3b2acfe73625..3eb555e0d80d 100644 --- a/tensorrt_llm/serve/responses_utils.py +++ b/tensorrt_llm/serve/responses_utils.py @@ -161,11 +161,23 @@ def _parse_response_input( input_msg["output"]) elif input_msg["type"] == "reasoning": content = input_msg.get("content") or [] - if len(content) != 1: + if not content: + # The Responses API allows reasoning items without 'content' + # (e.g. when a prior turn is replayed and the reasoning text + # would have to be inferred from 'id' or recovered from + # 'encrypted_content', which is not implemented). Follow the + # standard fallback behavior and ignore such items. + logger.debug( + "Responses API: ignoring reasoning input item without " + "'content'") + msg = None + elif len(content) > 1: raise ValueError( - "Input item of type 'reasoning' must have exactly one " + "Input item of type 'reasoning' must have at most one " f"'content' element, got {len(content)}") - msg = Message.from_role_and_content(Role.ASSISTANT, content[0]["text"]) + else: + msg = Message.from_role_and_content(Role.ASSISTANT, + content[0]["text"]) elif input_msg["type"] == "function_call": msg = Message.from_role_and_content(Role.ASSISTANT, input_msg["arguments"]) From e47a8482845717ea04a70120dc54ea5340ad8d10 Mon Sep 17 00:00:00 2001 From: lonexreb Date: Sat, 26 Sep 2026 18:08:50 -0700 Subject: [PATCH 3/3] [None][chore] apply yapf formatting to reasoning fallback debug log Signed-off-by: lonexreb --- tensorrt_llm/serve/responses_utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tensorrt_llm/serve/responses_utils.py b/tensorrt_llm/serve/responses_utils.py index 3eb555e0d80d..88c495d20f9a 100644 --- a/tensorrt_llm/serve/responses_utils.py +++ b/tensorrt_llm/serve/responses_utils.py @@ -167,9 +167,8 @@ def _parse_response_input( # would have to be inferred from 'id' or recovered from # 'encrypted_content', which is not implemented). Follow the # standard fallback behavior and ignore such items. - logger.debug( - "Responses API: ignoring reasoning input item without " - "'content'") + logger.debug("Responses API: ignoring reasoning input item without " + "'content'") msg = None elif len(content) > 1: raise ValueError(