From 5f2cd8fd14bcd3b7f1e693dd741b5f1a3c338051 Mon Sep 17 00:00:00 2001 From: John Pugliesi Date: Fri, 24 Apr 2026 04:20:45 -0700 Subject: [PATCH] mcp: preserve transport errors in Write error chain (#888) mcp: preserve transport errors in Write error chain Custom RoundTrippers that return typed errors (e.g. for auth failures) have those errors flattened to strings by `%v`, making `errors.As` unusable for callers inspecting transport-level errors. This is inconsistent with the OAuth handler path (line 1807) which already uses `%w` to preserve errors for client inspection. Relates to #579 Co-authored-by: Maciej Kisiel --- mcp/streamable.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcp/streamable.go b/mcp/streamable.go index 1455238..b791a1f 100644 --- a/mcp/streamable.go +++ b/mcp/streamable.go @@ -1795,14 +1795,14 @@ func (c *streamableClientConn) Write(ctx context.Context, msg jsonrpc.Message) e // Failure to set headers means that the request was not sent. // Wrap with ErrRejected so the jsonrpc2 connection doesn't set writeErr // and permanently break the connection. - return nil, nil, fmt.Errorf("%s: %w: %v", requestSummary, jsonrpc2.ErrRejected, err) + return nil, nil, fmt.Errorf("%s: %w: %w", requestSummary, jsonrpc2.ErrRejected, err) } resp, err := c.client.Do(req) if err != nil { // Any error from client.Do means the request didn't reach the server. // Wrap with ErrRejected so the jsonrpc2 connection doesn't set writeErr // and permanently break the connection. - err = fmt.Errorf("%s: %w: %v", requestSummary, jsonrpc2.ErrRejected, err) + err = fmt.Errorf("%s: %w: %w", requestSummary, jsonrpc2.ErrRejected, err) } return req, resp, err }