Skip to main content
Every failure comes back as JSON with one field.
There are no plain-text error bodies, and there is no per-route error shape. One handler covers the whole app — Hono has no per-route encapsulation, so it cannot silently fail to apply to a subtree.

Validation errors

Body and parameter validation failures answer in the same envelope, with the failing path prefixed:
The first issue is reported. The path is dotted, so a nested field reads as body.tools.0.name.

Internal errors never echo their cause

A 500 says nothing else, deliberately. Database errors carry column names, constraint names and sometimes the offending value, and none of that belongs in a client’s hands. The same rule holds more strongly on the MCP endpoint, where a tool result goes into a model’s context and from there into whatever it says next.

Status codes

404 for another account’s resource

A resource that exists in a different account returns 404, never 403. MCPulse never confirms that an id exists outside your account, so ids cannot be probed. Both gates — “no such MCP” and “not yours” — give the same answer.

403 messages name the requirement

Role failures say what would have been enough:
Four that are worth recognising: A plan refusal reads the same way and names the plan rather than the role — Your plan allows 1 MCP. Upgrade to add more. See Plans and Roles and permissions.

Retrying

The SDK does not retry at all, on anything. A dropped batch costs a data point; an unbounded retry queue costs a customer their memory. See What is sent.