fix(server): return INVALID_PARAMS for unknown prompt in prompts/get (#955)

## Problem

`prompts/get` for a name that is not registered responds with JSON-RPC
`-32603` (INTERNAL_ERROR).

`handleGetPrompt` in `Server.kt` throws a bare
`IllegalArgumentException` when the prompt is missing.
`Protocol.respondWithError` maps any non-`McpException` cause to
`INTERNAL_ERROR`, so the client receives `-32603` for what is a
client-side bad parameter.

The sibling handler `handleReadResource` in the same file already throws
a typed `McpException(RESOURCE_NOT_FOUND)` for the equivalent not-found
case, which reaches the client as `-32002`. The two not-found paths are
inconsistent.

In JSON-RPC, `-32603` means the server hit an internal fault. Requesting
a prompt name that does not exist is a client error (an invalid `name`
parameter), so a client cannot tell "the prompt does not exist" apart
from "the server failed" and may retry a request that can never succeed.

## Change

Throw a typed `McpException(INVALID_PARAMS)` from `handleGetPrompt`,
consistent with `handleReadResource`. The message is unchanged.

`AbstractPromptIntegrationTest.testNonExistentPrompt` asserted `-32603`;
it now asserts `INVALID_PARAMS`.

If you would prefer a dedicated error code for this case instead of
`INVALID_PARAMS`, I am glad to adjust.
This commit is contained in:
Recoordinate 2026-09-10 05:00:31 +12:00 • committed by GitHub
commit b7047e77cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 6 additions and 3 deletions

View file

@ -698,8 +698,8 @@ abstract class AbstractPromptIntegrationTest : KotlinTestBase() {
val expectedMessage = "Prompt not found: non-existent-prompt"
withClue("Exception code should be INTERNAL_ERROR: -32603") {
exception.code shouldBe -32603
withClue("Exception code should be INVALID_PARAMS: ${RPCError.ErrorCode.INVALID_PARAMS}") {
exception.code shouldBe RPCError.ErrorCode.INVALID_PARAMS
}
withClue("Unexpected error message for non-existent prompt") {
exception.message shouldBe expectedMessage

View file

@ -682,7 +682,10 @@ public open class Server(
val prompt = promptRegistry.get(requestParams.name)
?: run {
logger.error { "Prompt not found: ${requestParams.name}" }
throw IllegalArgumentException("Prompt not found: ${requestParams.name}")
throw McpException(
code = RPCError.ErrorCode.INVALID_PARAMS,
message = "Prompt not found: ${requestParams.name}",
)
}
return prompt.run {
session.clientConnection.messageProvider(request)