rohitg00/ai-engineering-from-scratch · error · RpcProblem

-32601

-32601

Error message

Method not found: ${message.method}

What it means

dispatch looked up message.method in the HANDLERS table and found no entry, so it returns JSON-RPC -32601 Method not found with the method name embedded in the message. This fires only after validateRequest passed, i.e. the envelope was fine.

Source

Thrown at phases/13-tools-and-protocols/07-building-an-mcp-server/code/main.ts:359

const HANDLERS: Record<string, (params: JsonObject) => JsonObject> = {
  "prompts/get": handlePromptsGet,
  "prompts/list": handlePromptsList,
  "resources/list": handleResourcesList,
  "resources/read": handleResourcesRead,
  "server/discover": handleDiscover,
  "tools/call": handleToolsCall,
  "tools/list": handleToolsList,
};

function dispatch(message: JsonRpcRequest): JsonRpcResponse | null {
  if (message.id === undefined) return null;
  const id = message.id;
  const errorId = isValidRequestId(id) ? id : null;
  try {
    validateRequest(message);
    const handler = HANDLERS[message.method];
    if (!handler) throw new RpcProblem(-32601, `Method not found: ${message.method}`);
    return { jsonrpc: "2.0", id, result: handler(message.params ?? {}) };
  } catch (error) {
    if (error instanceof RpcProblem) return rpcError(errorId, error.code, error.message, error.data);
    return rpcError(errorId, -32603, "Internal error", { detail: String(error) });
  }
}

function serveStdio(): void {
  const reader = createInterface({ input: process.stdin, terminal: false });
  reader.on("line", (line) => {
    if (!line.trim()) return;
    let response: JsonRpcResponse | null;
    try {
      const parsed = JSON.parse(line) as unknown;
      response =
        parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)
          ? dispatch(parsed as JsonRpcRequest)
          : rpcError(null, -32600, "Invalid Request");

View on GitHub (pinned to 39ea8a1c6d)

Solutions

  1. Inspect the HANDLERS map in main.ts for the exact supported method names
  2. Check spelling and casing of the method string
  3. Gate optional feature calls behind the capabilities the server advertised at initialize
Defensive patterns

Strategy: try-catch

Validate before calling

const SUPPORTED = new Set(Object.keys(HANDLERS)); 
if (!SUPPORTED.has(method)) throw new Error('unsupported method');

Try / catch

catch (e) { if (e instanceof RpcProblem && e.code === -32601) degradeGracefully(); }

Prevention

When it happens

Trigger: Calling methods like 'sampling/createMessage', 'roots/list', or any typo ('tools/lsit') that this teaching server does not register in HANDLERS.

Common situations: Clients using newer or optional MCP methods the server never implemented, or assuming auto-discovery of methods.

Related errors


AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26). Data as JSON: /api/errors/cf4ca5325b74deb9. Report an issue: GitHub.