Skip to content

fix(mcp): substitute static error envelope on encode failure instead of writing empty body#1146

Merged
datlechin merged 1 commit into
mainfrom
fix/mcp-encode-failure-no-empty-body
May 9, 2026
Merged

fix(mcp): substitute static error envelope on encode failure instead of writing empty body#1146
datlechin merged 1 commit into
mainfrom
fix/mcp-encode-failure-no-empty-body

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

  • MCPExchangeResponder.respond no longer falls back to Data() when the primary encode fails AND the secondary internal-error envelope encode also fails. The two-tier path now ends in a hardcoded static envelope {"jsonrpc":"2.0","id":null,"error":{"code":-32603,"message":"internal_error"}}.
  • MCPExchangeResponder.respondError and MCPExchangeResponder.reject use the same static fallback when JSONEncoder().encode(envelope) fails.
  • MCPHttpRequestRouter.handleIntegrationsExchange (success path) writes internalServerError with internal_error body via writePlainJsonError(...) if encoding ExchangeResponse fails, instead of writing a 200 with an empty body.
  • MCPHttpRequestRouter.respondTopLevel uses the same static JSON-RPC envelope fallback when encoding the top-level error envelope fails.
  • Each new failure path logs at error level with the encode error description.

Why this matters

This is bug B8 from the full-app audit. Five sites in the MCP HTTP transport previously did (try? JSONEncoder().encode(envelope)) ?? Data(). An MCP client receiving a zero-byte body on a 200 OK or a 500 response sees a protocol violation, then either disconnects or hangs waiting for a frame that will never arrive. The fix gives the client a valid JSON-RPC error envelope (or a small JSON internal_error for the non-RPC pairing endpoint), so the failure surface is observable from both sides.

The static envelope is a literal Data value, not a re-encode, so it cannot itself fail.

Test plan

  • Manual: send a request that produces a non-encodable JsonRpcMessage (synthetic NaN if injected), confirm Console shows the encode-failed log and the client receives the static internal_error envelope rather than a zero-byte body.
  • Manual: pairing exchange flow under normal conditions still returns the token JSON.
  • swiftlint --strict clean.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin datlechin merged commit 3e50af8 into main May 9, 2026
2 checks passed
@datlechin datlechin deleted the fix/mcp-encode-failure-no-empty-body branch May 9, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant