# JSON-RPC error codes are used correctly

- **Pattern:** `ab-001840` (`mcp-server.error-resilience.structured-errors`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001840
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001840)

## Why it matters

JSON-RPC error codes carry semantic meaning that MCP clients use to determine how to display and recover from errors. Using HTTP-style codes (404, 500) instead of JSON-RPC codes (-32601, -32603) causes client error handlers to misclassify failures — a method-not-found error processed as an internal error may suppress retry logic or show the wrong message. CWE-703 (improper check or handling of exceptional conditions) applies: error codes must accurately describe the failure type for clients to respond correctly, especially in automated AI workflows where error classification drives next-step decisions.

## Severity rationale

High because incorrect error codes cause clients to mishandle failures — retrying internal errors, suppressing user-facing messages, or misrouting recoverable vs. non-recoverable conditions.

## Remediation

Use the standard JSON-RPC error codes. The MCP SDK exports `ErrorCode` and `McpError` — use them instead of constructing error objects manually.

```ts
// src/errors.ts — structured MCP errors
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'

// In tool handlers:
throw new McpError(ErrorCode.InvalidParams, 'Missing required parameter: query')

// In custom message routers:
const METHOD_NOT_FOUND = -32601
const INVALID_PARAMS   = -32602
const INTERNAL_ERROR   = -32603

return {
  jsonrpc: '2.0',
  id: request.id,
  error: { code: METHOD_NOT_FOUND, message: `Unknown method: ${request.method}` }
}
```

Custom server error codes must be in the range `-32000` to `-32099` — never use HTTP status codes.

## Detection

- **ID:** `structured-errors`
- **Severity:** `high`
- **What to look for:** Count all error responses in the server. Enumerate which use MCP error codes (-32600, -32601, -32602, -32603) vs. generic error messages. Check all error responses in the codebase. JSON-RPC 2.0 defines standard error codes: -32700 (Parse error), -32600 (Invalid Request), -32601 (Method not found), -32602 (Invalid params), -32603 (Internal error). Check that the server uses these codes correctly in error responses. Check that custom error codes (if any) are in the allowed range (-32000 to -32099 for server errors). Check that error responses always include both `code` (integer) and `message` (string).
- **Pass criteria:** Error responses use standard JSON-RPC error codes correctly. Custom error codes are in the valid range. Every error response includes `code` and `message`. Error codes match the actual error type (e.g., -32601 for unknown methods, not -32600). At least 90% of error responses must use standard JSON-RPC/MCP error codes.
- **Fail criteria:** Non-standard error codes used, error responses missing `code` or `message` fields, or incorrect codes for the error type (e.g., using -32700 for invalid params).
- **Skip (N/A) when:** All checks skip when no MCP server is detected.
- **Do NOT pass when:** Error responses return HTTP status codes instead of JSON-RPC error objects, or use non-standard error code numbers.

- **Cross-reference:** For tool-level error handling, see `tool-error-catch`.
- **Detail on fail:** `"Error responses use HTTP-style codes (404, 500) instead of JSON-RPC codes (-32601, -32603). Code '500' is not a valid JSON-RPC error code"` or `"Error response for unknown method uses code -32600 (Invalid Request) instead of -32601 (Method not found)"`
- **Remediation:** Use the correct JSON-RPC error codes:

  ```ts
  // src/errors.ts — structured MCP error
  throw new McpError(ErrorCode.InvalidParams, "Missing required parameter: query")
  ```

  ```ts
  // Standard JSON-RPC error codes
  const PARSE_ERROR = -32700       // Invalid JSON
  const INVALID_REQUEST = -32600   // Not a valid Request object
  const METHOD_NOT_FOUND = -32601  // Method does not exist
  const INVALID_PARAMS = -32602    // Invalid method parameters
  const INTERNAL_ERROR = -32603    // Internal server error

  // In error responses
  return {
    jsonrpc: '2.0',
    id: request.id,
    error: { code: METHOD_NOT_FOUND, message: `Unknown method: ${request.method}` }
  }
  ```

## External references

- cwe CWE-703
- external jsonrpc-2.0-error-codes — https://www.jsonrpc.org/specification#error_object

Taxons: error-resilience, inference-contract

HTML version: https://auditbuffet.com/patterns/ab-001840
