Skip to content

mcp: avoid panicking when a resource handler returns nil - #1176

Merged
guglielmo-san merged 1 commit into
modelcontextprotocol:mainfrom
latent-9:readresource-nil-result
Aug 17, 2026
Merged

mcp: avoid panicking when a resource handler returns nil#1176
guglielmo-san merged 1 commit into
modelcontextprotocol:mainfrom
latent-9:readresource-nil-result

Conversation

@latent-9

Copy link
Copy Markdown
Contributor

What

readResource dereferenced the handler's result before the if res == nil
check that was meant to guard it. A ResourceHandler returning (nil, nil)
therefore panicked instead of returning an error:

  • modern clients: handleMultiRoundTripResult calls res.setResultType on the
    nil result, and
  • older clients: res.setDefaultCacheableValues() runs on the nil result.

Either way the if res == nil guard a few lines below was dead code.

Why it matters

Request handlers run in their own goroutine and nothing recovers, so the panic
does not just fail the one request. It terminates the whole server process and
every concurrent session.

The sibling handlers already avoid this: callTool and getPrompt both guard
their result with if err == nil && res != nil before touching it, so a
(nil, nil) return flows up and becomes a normal error response.

Change

Move the nil check in readResource ahead of handleMultiRoundTripResult and
setDefaultCacheableValues, so a nil result returns the existing descriptive
error (read handler returned nil information) instead of panicking. Added a
regression test that drives a resource handler returning (nil, nil) through
the server and asserts a clean error.

readResource dereferenced the handler's result before the nil check that
was meant to guard it, so a ResourceHandler returning (nil, nil) crashed
the server with a nil pointer panic instead of returning an error.

Request handlers run in their own goroutine with no recover, so that panic
terminates the whole process and every concurrent session, not just the
offending request.

The sibling handlers callTool and getPrompt already guard their result with
`if err == nil && res != nil` before touching it. Move the nil check in
readResource ahead of handleMultiRoundTripResult and setDefaultCacheableValues
so a nil result returns the existing descriptive error, and add a regression
test.
@guglielmo-san
guglielmo-san merged commit 0eb1600 into modelcontextprotocol:main Aug 17, 2026
9 checks passed
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.

2 participants