rohitg00/ai-engineering-from-scratch · error · RpcProblem
-32600
-32600
Error message
Invalid Request
What it means
The server rejects an incoming JSON-RPC message whose envelope is not a valid 2.0 request: jsonrpc must be the exact string '2.0' and method must be a string. This is the JSON-RPC 2.0 spec's Invalid Request code (-32600), thrown by validateRequest before any handler runs.
Source
Thrown at phases/13-tools-and-protocols/07-building-an-mcp-server/code/main.ts:160
if (data !== undefined) error.data = data;
return { jsonrpc: "2.0", id, error };
}
function complete(
payload: JsonObject,
cache?: { ttlMs: number; cacheScope: "private" | "public" },
): JsonObject {
return {
resultType: "complete",
...payload,
...(cache ?? {}),
_meta: { [SERVER_INFO_KEY]: { ...SERVER_INFO } },
};
}
function validateRequest(message: JsonRpcRequest): void {
if (message.jsonrpc !== "2.0" || typeof message.method !== "string") {
throw new RpcProblem(-32600, "Invalid Request");
}
const requestId: unknown = message.id;
if (requestId !== undefined && !isValidRequestId(requestId)) {
throw new RpcProblem(-32600, "id must be a string or integer");
}
const params = message.params;
if (!params || typeof params !== "object" || Array.isArray(params)) {
throw new RpcProblem(-32602, "params must be an object");
}
const meta = params._meta;
if (!meta || typeof meta !== "object" || Array.isArray(meta)) {
throw new RpcProblem(-32602, "params._meta is required");
}
const requested = meta[VERSION_KEY];
if (typeof requested !== "string") {
throw new RpcProblem(-32602, `${VERSION_KEY} is required`);
}
if (!SUPPORTED_VERSIONS.includes(requested)) {View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Set jsonrpc:'2.0' and a string method on every request sent to dispatch
- Log the raw message before dispatch to see exactly which field is wrong
- If writing a client, centralize envelope construction in one helper so the field can never be missed
Example fix
// before
dispatch({ id: 1, method: 'initialize', params: { _meta: {} } });
// after
dispatch({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { _meta: {} } }); Defensive patterns
Strategy: validation
Validate before calling
function isValidEnvelope(m: unknown): boolean {
return typeof m === 'object' && m !== null
&& (m as any).jsonrpc === '2.0'
&& typeof (m as any).method === 'string';
}
if (!isValidEnvelope(msg)) throw new Error('bad envelope'); Type guard
function isJsonRpcRequest(m: unknown): m is { jsonrpc: '2.0'; method: string } {
return typeof m === 'object' && m !== null && (m as Record<string, unknown>).jsonrpc === '2.0'
&& typeof (m as Record<string, unknown>).method === 'string';
} Try / catch
try { dispatch(msg); } catch (e) { if (e instanceof RpcProblem && e.code === -32600) fixEnvelopeAndRetry(); else throw e; } Prevention
- Build every request through one typed helper that hardcodes jsonrpc:'2.0'
- Assert the envelope in unit tests of the client
When it happens
Trigger: dispatch() receives a message with jsonrpc:'1.0' or missing, a numeric method like method:42, or a notification-shaped payload with a non-string method field.
Common situations: Hand-rolled stdio clients forgetting the jsonrpc:'2.0' field, JSON pipelines that mangle keys, or tests reusing JSON-RPC 1.0 style payloads ({id, method, params} without the version field).
Related errors
- name must be a non-empty string
- -32602
- -32603
- -32601
- Budget.step requires non-negative tokens and dollars
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/00e6c4eb76e7f80c.
Report an issue: GitHub.