From f5c4d3e1775f81e02a69c304c040c1b456c2b3a6 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 26 Jun 2026 03:10:08 +0000 Subject: [PATCH] fix(validation): only match tool_use/tool_result IDs when last message has tool_result Fixes #2960 Move the ID-matching check inside the has_tool_results block so validate_tool_use_result_messages() does not raise when a previous tool_use is followed by a plain text response without tool_result. --- src/mcp/server/validation.py | 1 - tests/server/test_validation.py | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/mcp/server/validation.py b/src/mcp/server/validation.py index fd16beb95..4fa71c103 100644 --- a/src/mcp/server/validation.py +++ b/src/mcp/server/validation.py @@ -81,7 +81,6 @@ def validate_tool_use_result_messages(messages: list[SamplingMessage]) -> None: if not has_previous_tool_use: raise ValueError("tool_result blocks do not match any tool_use in the previous message") - if has_previous_tool_use and previous_content: tool_use_ids = {c.id for c in previous_content if c.type == "tool_use"} tool_result_ids = {c.tool_use_id for c in last_content if c.type == "tool_result"} if tool_use_ids != tool_result_ids: diff --git a/tests/server/test_validation.py b/tests/server/test_validation.py index 8015c34dd..a523b0672 100644 --- a/tests/server/test_validation.py +++ b/tests/server/test_validation.py @@ -146,6 +146,24 @@ def test_validate_tool_use_result_messages_raises_when_tool_result_ids_dont_matc validate_tool_use_result_messages(messages) +def test_validate_tool_use_result_messages_no_error_when_tool_use_not_followed_by_tool_result() -> None: + """No error when previous message has tool_use but last message has no tool_result.""" + messages = [ + SamplingMessage( + role="assistant", + content=[ + TextContent(type="text", text="Hold on..."), + ToolUseContent(type="tool_use", id="abc", name="search", input={"q": "test"}), + ], + ), + SamplingMessage( + role="user", + content=TextContent(type="text", text="Thanks, no results needed"), + ), + ] + validate_tool_use_result_messages(messages) # Should not raise + + def test_validate_tool_use_result_messages_no_error_when_tool_result_matches_tool_use() -> None: """No error when tool_result IDs match tool_use IDs.""" messages = [