From 03d48376166a550454886f4205304fd64e1a38ed Mon Sep 17 00:00:00 2001 From: Yashwant Bezawada Date: Sat, 15 Nov 2025 16:35:42 -0600 Subject: [PATCH] Fix: Only include updatedInput when explicitly provided in permission callbacks Fixes #1063 When a permission callback returns `PermissionResultAllow()` without the `updated_input` parameter, the SDK should not include `updatedInput` in the control_response. Previously, the SDK always included this field, either with the modified input or falling back to the original input, which caused MCP tools to receive empty {} arguments instead of Claude's original arguments. Changes: - Modified query.py to only include updatedInput when explicitly set - Added regression test to verify updatedInput is omitted when not provided - Existing test for input modification still passes Before this fix: ```json { "behavior": "allow", "updatedInput": {} // Bug: Always included even when not set } ``` After this fix: ```json { "behavior": "allow" // updatedInput only included when explicitly provided } ``` --- src/claude_agent_sdk/_internal/query.py | 12 ++++-------- tests/test_tool_callbacks.py | 7 +++++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/claude_agent_sdk/_internal/query.py b/src/claude_agent_sdk/_internal/query.py index 7646010..1f549c7 100644 --- a/src/claude_agent_sdk/_internal/query.py +++ b/src/claude_agent_sdk/_internal/query.py @@ -233,14 +233,10 @@ class Query: # Convert PermissionResult to expected dict format if isinstance(response, PermissionResultAllow): - response_data = { - "behavior": "allow", - "updatedInput": ( - response.updated_input - if response.updated_input is not None - else original_input - ), - } + response_data = {"behavior": "allow"} + # Only include updatedInput if explicitly provided by the user + if response.updated_input is not None: + response_data["updatedInput"] = response.updated_input if response.updated_permissions is not None: response_data["updatedPermissions"] = [ permission.to_dict() diff --git a/tests/test_tool_callbacks.py b/tests/test_tool_callbacks.py index 8ace3c8..7811406 100644 --- a/tests/test_tool_callbacks.py +++ b/tests/test_tool_callbacks.py @@ -96,6 +96,13 @@ class TestToolPermissionCallbacks: response = transport.written_messages[0] assert '"behavior": "allow"' in response + # IMPORTANT: Verify updatedInput is NOT included when not provided + # This is the regression test for issue #1063 + assert '"updatedInput"' not in response, ( + "updatedInput should not be included when PermissionResultAllow() " + "is returned without updated_input parameter" + ) + @pytest.mark.asyncio async def test_permission_callback_deny(self): """Test callback that denies tool execution."""