> ## Documentation Index
> Fetch the complete documentation index at: https://docs.particle.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> How tool errors surface in MCP responses, and how the REST error catalog maps onto them.

The MCP server surfaces three distinct kinds of failures, each with a different shape. This page explains how to recognize and react to each one.

## 1. Authentication / authorization failures (HTTP)

If the bearer token is missing, malformed, expired, or revoked, the MCP endpoint returns an HTTP `401 Unauthorized` *before* the request reaches the tool layer. The response carries an RFC 9728 `WWW-Authenticate` challenge:

```http theme={"dark"}
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="mcp", error="invalid_token", resource_metadata="https://mcp.particle.pro/.well-known/oauth-protected-resource"
Content-Type: text/plain

grant revoked or unknown
```

The human-readable explanation lives in the response body. The header carries only the structured fields (`realm`, `error`, optional `scope`, `resource_metadata`).

Reactions:

* Re-run the OAuth flow. The `resource_metadata` URL is the authoritative pointer to the AS — do not hard-code the token endpoint.
* For revoked grants, the user must reconnect — see [Manage connections](/mcp/authentication#manage-connections).
* If the request authenticated with a [platform API key](/mcp/authentication#api-keys-for-headless-agents) instead of OAuth, a bad key gets the same `401` shape with the body `invalid or expired API key` — rotate or re-issue the key from the project settings; the OAuth challenge in the header does not apply to you.

See [Authentication](/mcp/authentication) for the full validation pipeline.

## 2. Subscription / rate-limit failures (HTTP)

Requests that pass authentication but hit a subscription block or per-org rate limit return RFC 9457 `application/problem+json` bodies — the same shape as the REST API. The response is HTTP, not an MCP tool result, because the request never reached a tool.

```http theme={"dark"}
HTTP/1.1 402 Payment Required
Content-Type: application/problem+json

{
  "type": "https://docs.particle.pro/errors/spend_limit_exceeded",
  "title": "Payment Required",
  "status": 402,
  "detail": "Spend limit reached for the current billing period.",
  "error_code": "spend_limit_exceeded",
  "resolve": {
    "message": "Increase the spend limit or upgrade the plan to continue.",
    "url": "https://platform.particle.pro/organizations/<orgId>/billing",
    "action": "update_spend_limits",
    "method": "POST",
    "endpoint": "/v1/organizations/<orgId>/billing/spend-limits"
  }
}
```

The full set of codes is documented in [REST → Errors](/errors/overview). The ones an MCP client is most likely to see at this layer:

* [`spend_limit_exceeded`](/errors/spend_limit_exceeded), [`credits_depleted`](/errors/credits_depleted), [`rate_limit_exceeded`](/errors/rate_limit_exceeded)
* [`subscription_suspended`](/errors/subscription_suspended), [`payment_past_due`](/errors/payment_past_due), [`subscription_inactive`](/errors/subscription_inactive)
* [`pro_required`](/errors/pro_required), [`not_a_member`](/errors/not_a_member)

Branch on `error_code`; surface `resolve.message` and `resolve.url` to the user. Agents that can take action programmatically should use `resolve.action`, `resolve.method`, and `resolve.endpoint`.

## 3. Tool-level failures (MCP `isError: true`)

When a request reaches a tool but the tool itself fails (missing required parameter, slug not found, invalid date, downstream handler error), the MCP server returns a `200 OK` HTTP response carrying an MCP `CallToolResult` with `isError: true` and a single text content block:

```json theme={"dark"}
{
  "jsonrpc": "2.0",
  "id": 17,
  "result": {
    "isError": true,
    "content": [
      {
        "type": "text",
        "text": "**Error code:** missing_parameter\n\ntool particle_entity_resolve requires parameter `query` (e.g. query=\"sam altman\")"
      }
    ]
  }
}
```

Every tool error leads with a `**Error code:** <slug>` line — a stable, machine-readable code to branch on without substring-matching the prose that follows. Two kinds of codes appear:

* **MCP-only codes** for failures that never reach the REST layer: `missing_parameter`, `invalid_parameter`, `invalid_input` (malformed arguments), and `unknown_tool` (a `particle_call` dispatch to a name that doesn't exist on the public surface).
* **REST catalog codes** reused as-is when the underlying handler fails — e.g. `not_found`, `bad_request`, `premium_required`. See [REST → Errors](/errors/overview) for the full catalog.

After the code line comes the handler's message, and — where the server knows a better next move than a blind retry — a course-correcting suggestion. Structured `resolve` guidance from the REST layer (message + URL) is folded into that suggestion; common statuses get a default:

* **404** suggests re-resolving the identifier first (`particle_podcast_resolve`, `particle_person_resolve`, `particle_company_resolve`, or `particle_entity_resolve`) and retrying with the returned slug.
* **400/422** suggests checking the parameter constraints via [`particle_catalog`](/mcp/tools/system/catalog) with the tool's category, which returns the full input schema.

Reactions:

* Branch on the `**Error code:**` slug, then follow the suggestion in the text — it names the exact tool to call next.
* For `missing_parameter` / `invalid_parameter`, the text includes a usage hint (e.g. `query="sam altman"`) — fix the call and retry.
* For `internal_error`, surface the message to the user and avoid retry loops — the resource server logs the underlying error with full structure for support follow-up.

## Why three layers?

* **HTTP 401** is the only path that's defined by RFC 6750 / RFC 9728 — MCP clients that follow the OAuth spec already handle it. Putting auth errors anywhere else would break the discovery loop.
* **HTTP 402/403/429** with RFC 9457 bodies stays consistent with the REST API: the same billing or rate-limit middleware runs in front of both surfaces, so the same problem-details shape comes out.
* **`isError: true` MCP results** are how the spec recommends per-tool failures be returned — a `200 OK` JSON-RPC response with the structured error in the result envelope, so the agent can keep the session open and fix the call.

## See also

* [REST → Errors](/errors/overview) — the canonical catalog of `error_code` values and resolution actions.
* [Authentication](/mcp/authentication) — how 401s arise and what `WWW-Authenticate` carries.
* [Tool reference](/mcp/tools/overview) — every tool documents its required parameters and the failure modes it can raise.
