From db5ec90e02b787dd2d423427a3ab3594a958bda8 Mon Sep 17 00:00:00 2001 From: MUHAMMAD SALMAN HUSSAIN <160324527+mshsheikh@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:35:11 +0500 Subject: [PATCH 1/2] fix(mcp): chain JSON decode errors during tool invocation When tool input JSON parsing fails in `invoke_mcp_tool()`, the resulting `ModelBehaviorError` should always preserve the original `JSONDecodeError` as its cause. Today, the `_debug.DONT_LOG_TOOL_DATA` path raises `ModelBehaviorError` without exception chaining, which drops the original parse failure from the traceback and makes debugging harder. The OpenAI Agents SDK issue tracker also calls out this error path as a source of unsafe or unclear malformed-input handling. This change removes the early raise in the debug-suppressed branch and ensures the function always raises `ModelBehaviorError(...) from json_decode_error`. That keeps the user-facing message generic, avoids logging raw payload data in the sensitive path, and still preserves the root cause for debugging through `__cause__`. The behavior stays consistent with the non-debug branch while improving observability and error traceability. Testing: - Add a regression test for malformed JSON with `DONT_LOG_TOOL_DATA=True` and assert the original exception is chained - Add a regression test for malformed JSON with `DONT_LOG_TOOL_DATA=False` and assert the message still includes the input payload as expected - Verify the raised exception type remains `ModelBehaviorError` in both branches --- src/agents/mcp/util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/agents/mcp/util.py b/src/agents/mcp/util.py index bf00cb2b79..a02db45444 100644 --- a/src/agents/mcp/util.py +++ b/src/agents/mcp/util.py @@ -592,7 +592,6 @@ async def invoke_mcp_tool( error_message = f"Invalid JSON input for tool {tool_name_for_display}" if _debug.DONT_LOG_TOOL_DATA: logger.debug(error_message) - raise ModelBehaviorError(error_message) else: error_message = f"{error_message}: {input_json}" logger.debug(error_message) From f247c382d5a32f88698d8aaff1b36d024032ec7a Mon Sep 17 00:00:00 2001 From: MUHAMMAD SALMAN HUSSAIN <160324527+mshsheikh@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:46:34 +0500 Subject: [PATCH 2/2] fix(mcp): preserve JSON decode causes without exposing redacted input When MCP tool argument parsing fails in `invoke_mcp_tool()`, the error handling should preserve debugging information only when it is safe to do so. In the non-redacted path, the raised `ModelBehaviorError` should continue to chain the original `JSONDecodeError`, since that helps preserve the root cause for debugging and keeps the failure mode easy to trace. In the redacted path (`_debug.DONT_LOG_TOOL_DATA=True`), the original `JSONDecodeError` must not be chained, because `json.JSONDecodeError` retains the raw malformed input in its internal state. Chaining that exception would make it possible to recover sensitive tool input through exception inspection, which defeats the purpose of the redaction path. This change keeps the existing privacy protection in the sensitive path while still preserving useful error causality in the non-redacted path: - redacted path: raise `ModelBehaviorError(...) from None` - non-redacted path: raise `ModelBehaviorError(...) from json_decode_error` This keeps the behavior consistent, safer, and easier to debug without exposing raw malformed input when logging is disabled. --- src/agents/mcp/util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/agents/mcp/util.py b/src/agents/mcp/util.py index a02db45444..3646d79da7 100644 --- a/src/agents/mcp/util.py +++ b/src/agents/mcp/util.py @@ -592,10 +592,11 @@ async def invoke_mcp_tool( error_message = f"Invalid JSON input for tool {tool_name_for_display}" if _debug.DONT_LOG_TOOL_DATA: logger.debug(error_message) + raise ModelBehaviorError(error_message) from None else: error_message = f"{error_message}: {input_json}" logger.debug(error_message) - raise ModelBehaviorError(error_message) from json_decode_error + raise ModelBehaviorError(error_message) from json_decode_error if not isinstance(json_data, dict): raise ModelBehaviorError(