Skip to content

fix(core): send an error response when a request handler rejects with a nullish reason#2521

Draft
lntutor wants to merge 1 commit into
modelcontextprotocol:mainfrom
lntutor:fix/nullish-handler-rejection
Draft

fix(core): send an error response when a request handler rejects with a nullish reason#2521
lntutor wants to merge 1 commit into
modelcontextprotocol:mainfrom
lntutor:fix/nullish-handler-rejection

Conversation

@lntutor

@lntutor lntutor commented Jul 19, 2026

Copy link
Copy Markdown

Draft only because this repo caps non-collaborators at one non-draft open PR at a time (#2519 holds it). Change is complete, tested, and review-ready.

What's broken

Protocol's inbound-request error path reads error['code'] directly. When a handler rejects with null/undefined (a bare reject() or throw null in library code), that indexing throws a TypeError inside the rejection callback, which propagates to the outer .catch — so no JSON-RPC error response is ever sent and the requester hangs until its own timeout.

Fix

Coalesce the rejection reason to a safe object before reading code/message/data, so a -32603 Internal error response is always returned.

Tests

New test in packages/core-internal/test/shared/protocol.test.ts: a handler that Promise.reject(undefined) now produces an error response for the request id (before the fix, none was sent). Full core-internal suite passes (1376 tests), typecheck + lint clean. Changeset included.

🤖 Generated with Claude Code

… a nullish reason

Protocol's inbound-request error path read error['code'] directly. When a
handler rejects with null/undefined (a bare reject() or throw null), that
indexing throws a TypeError inside the rejection callback, which
propagates to the outer .catch — so no JSON-RPC error response is ever
sent and the requester hangs until its own timeout.

Coalesce the reason to a safe object before reading the code/message/data,
so a -32603 Internal error response is always returned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N6RtoHuxrDqTUo9Mw9h4Cv
@changeset-bot

changeset-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e3cf478

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/core Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/core-internal Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/server Patch
@modelcontextprotocol/codemod Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2521

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2521

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2521

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2521

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2521

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2521

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2521

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2521

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2521

commit: e3cf478

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