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

# Error reference

> Error shapes, codes, and recovery for Mini App page, Node, Agent, and lifecycle APIs.

This page describes Mini App interfaces available in official releases and their error handling, with version differences noted in the relevant sections. Method signatures are in [Client API](https://agent.minimax.io/docs/miniapp/reference/client-api.md), [Node API](https://agent.minimax.io/docs/miniapp/reference/node-api.md), and [Agent API](https://agent.minimax.io/docs/miniapp/reference/agent-api.md).

## Identify the error shape first

| Entry point | Read | Recovery basis |
| - | - | - |
| Page `window.mcode.miniapp` | The thrown or rejected `Error.message`, using lowercase codes | Use the method's table; do not assume Node `code`, `reason`, or `permissions` survives the page bridge |
| Node `context.hostConnector` / `context.tool` | `code`, `disposition`, `retryable`, and optional `invocationId` and `diagnostic` | `disposition` determines dispatch state; the same timeout or cancellation code can have different outcomes |
| Node `context.agent` | `code`, `retryable`, and possibly `reason` with `BUSY` | `retryable` means nothing started and the call may be retried later; do not repeat a turn with an unknown outcome |
| The Agent's `miniapp` lifecycle tool | `{ ok: false, action, error }` | Inspect `error.code`, `retryable`, and optional `diagnostic`; this is not a rejected page Promise |

Do not depend on `instanceof` or a concrete Error subclass across process boundaries. Use `message` for display or diagnostics and `code` for Node business branches.

## miniapp tool

These errors belong to the Agent tool used for `init`, `publish`, `open`, `inspect`, `restart`, and `stop`, rather than Node `context.tool`.

| `error.code` | Meaning and handling |
| - | - |
| `INVALID_ARGUMENTS` | Invalid action or argument combination; correct it before retrying |
| `NOT_FOUND` | The Mini App was not found; check `pluginId` and installation |
| `NOT_ENABLED` | The plugin is disabled; enable it first |
| `PLUGIN_ALREADY_EXISTS` | A plugin with the same name exists; inspect `diagnostic`, and do not overwrite an official package with local publishing |
| `BUSY` | Inspect `busyReason`: `operation_busy` means another action is in progress; `capacity_busy` means all three runtime slots are taken and a slot must be freed |
| `SERVICE_RESTARTED` | The service generation changed during the action; refresh state and follow `retryable` |
| `PREPARATION_FAILED` | Package, manifest, installation, or startup preparation failed; follow `diagnostic.recovery` and `hint` below |
| `RUNTIME_FAILED` | The runtime could not complete the action; inspect `runtimeError` and `inspect` rather than treating this as one root cause |
| `OPEN_UNAVAILABLE` | This host provides no surface for opening the page |
| `INTERNAL_ERROR` | Internal host failure; may include `diagnosticId` and `lastGoodAvailable`; retain diagnostics and do not repeat unchanged |
| `CANCELLED` | The action was cancelled; the user or application decides whether to start again |

`error.retryable` is a host recovery hint. Retrying `capacity_busy` does not free a slot. Even when `PREPARATION_FAILED` suggests a `retry` recovery, satisfy the condition in its hint first.

### Publishing diagnostics

`error.diagnostic` has `{ stage, reasonCode, recovery, hint }`. `stage` is `workspace`, `runtime`, `mcp`, `connector`, or `host`; `recovery` is `edit_workspace`, `retry`, or `user_action`. The following are public publishing `reasonCode` values, not top-level `error.code` values.

| `reasonCode` | What to check |
| - | - |
| `OFFICIAL_PLUGIN_READ_ONLY` | Official plugins cannot be edited or republished locally; accompanies `PLUGIN_ALREADY_EXISTS` |
| `MINIAPP_WORKSPACE_CANDIDATE_MISSING` | No candidate package in the current workspace; pass a finished directory with `sourcePath` |
| `MINIAPP_SOURCE_UNAVAILABLE`, `MINIAPP_SOURCE_INVALID` | Whether the supplied directory is readable and contains a complete package |
| `MINIAPP_SOURCE_IDENTITY_MISMATCH`, `MINIAPP_SOURCE_OVERLAP` | Whether the package matches `pluginId` and the source overlaps the installation directory |
| `WORKSPACE_PLUGIN_INVALID`, `MINIAPP_REFERENCE_INVALID` | `plugin.json` and the declaration entry in `package.json` |
| `MINIAPP_MANIFEST_INVALID`, `MINIAPP_MANIFEST_FIELD_UNSUPPORTED` | Manifest format, schema, and whether the host recognizes its fields |
| `MINIAPP_ARTIFACTS_INVALID`, `MINIAPP_RUNTIME_INVALID`, `MINIAPP_RUNTIME_ENTRY_INVALID` | Payload roots, process runtime declaration, and entry coverage |
| `MINIAPP_SURFACE_INVALID`, `MINIAPP_MCP_ENDPOINTS_INVALID` | Page route, window fields, and MCP endpoint declarations |
| `MINIAPP_CONNECTOR_ACCESS_INVALID`, `MINIAPP_AGENT_ACCESS_INVALID`, `MINIAPP_TOOL_ACCESS_INVALID`, `MINIAPP_DEVICE_ACCESS_INVALID` | Permission names, values, and host support |
| `MINIAPP_AGENT_CONCURRENCY_INVALID` | Whether concurrency is an integer from 1 to 32 |
| `MINIAPP_ENGINES_INVALID` | Whether `engines.mcode` uses the supported `>=MAJOR.MINOR.PATCH` syntax |
| `MINIAPP_HOST_TOO_OLD` | Whether the host satisfies `engines.mcode`; update it or verify that the package needs this minimum |
| `WORKSPACE_CHANGED`, `WORKSPACE_INSTALL_FAILED` | Concurrent edits during preparation, local installation conflicts, or file access |
| `RUNTIME_START_FAILED`, `RUNTIME_START_EXPORT_MISSING`, `RUNTIME_LIFECYCLE_INVALID`, `RUNTIME_NOT_READY` | Entry loading, the `start` export, its return value, and readiness |
| `MCP_INVENTORY_INVALID`, `MCP_INVENTORY_MISMATCH`, `MCP_PUBLICATION_INVALID` | MCP tool inventories, digests, and safe publication |
| `MCP_ENDPOINT_UNREACHABLE`, `MCP_PROTOCOL_INVALID` | Whether each endpoint is running and returns valid protocol responses |
| `HOST_CONNECTOR_UNAVAILABLE`, `HOST_CONNECTOR_PROTOCOL_INVALID` | Host bridge availability and use of the public Connector API |
| `HOST_CAPACITY_UNAVAILABLE` | Whether to stop an unused Mini App or wait for the current action |

## Node outcomes and retries

Host Connector and the unified tool entry share these error fields:

```typescript theme={null}
interface HostCallError extends Error {
  code: string; // Public codes are listed below.
  disposition: 'not_dispatched' | 'provider_reported' | 'unknown_after_dispatch';
  retryable: boolean;
  invocationId?: string;
  diagnostic?: {
    issues: { path: string; constraint: string; limit?: number }[];
  };
}
```

* `not_dispatched`: nothing was sent to the target; address the cause before considering a retry.
* `provider_reported`: the provider returned a failure. Interpret its business outcome; this does not prove that no write occurred.
* `unknown_after_dispatch`: the call may have executed. Read business state first and do not repeat a write based only on an error name or retry hint.
* `invocationId` correlates the call and may be absent. `diagnostic.issues` contains safe field paths, constraints, and limits, not user argument values.

## Host Connector

| Node `code` | Meaning and handling |
| - | - |
| `TOOL_REF_STALE` | The reference expired; call `list()` again instead of constructing a `toolRef` |
| `SERVICE_RESTARTED` | The service restarted before dispatch; list tools again and check current state |
| `REQUEST_CANCELLED` | The request was cancelled; still inspect `disposition` rather than inferring non-execution from its name |
| `CONNECTOR_TIMEOUT` | Waiting timed out before dispatch; loss of confirmation after dispatch is treated as an unknown outcome |
| `INVALID_ARGUMENTS` | Invalid local input, arguments that do not match the schema, or a request exceeding the 256 KiB JSON limit; inspect `diagnostic.issues` when present and reduce oversized arguments |
| `CONNECTOR_NOT_PERMITTED` | The user switched this provider off; nothing was sent and the user must re-enable it |
| `CONNECTOR_PROVIDER_ERROR` | The provider reported a failure; this does not always mean authorization expired |
| `CONNECTOR_UNAVAILABLE` | Connector calls are unavailable for this generation; follow `retryable` |
| `CONNECTOR_OUTCOME_UNKNOWN` | Confirmation was lost after dispatch, including transport failure, timeout, or cancellation; reconcile business state first |

See [Node API](https://agent.minimax.io/docs/miniapp/reference/node-api.md#connector) for signatures and result structures.

## Node unified tool entry

`context.tool` uses the Node error shape above. Calling a Connector tool can also retain [Host Connector codes](https://agent.minimax.io/docs/miniapp/reference/errors.md#connector).

| Node `code` | Meaning and handling |
| - | - |
| `INVALID_ARGUMENTS` | Invalid tool name, JSON arguments, permission request list, or a request exceeding the 256 KiB JSON limit; confirm names and schemas with `list()` and reduce oversized arguments. `diagnostic` may be absent |
| `TOOL_NOT_PERMITTED` | Missing call access, `tool:call` switched off, a `deny` rule, or the user denied this call |
| `TOOL_APPROVAL_REQUIRED` | Confirmation is needed but nobody can answer; request permission from an interactive host surface |
| `TOOL_UNAVAILABLE` | Tools are unavailable for this process generation or channel |
| `TOOL_REF_STALE` | The runtime tool name is no longer available; list again |
| `TOOL_TIMEOUT` | The approval or execution phase timed out; `disposition` distinguishes no dispatch from an unknown outcome after dispatch |
| `TOOL_RESULT_TOO_LARGE` | The result exceeded the response-frame limit; the call may have executed, so inspect `disposition` and reduce the business result |
| `TOOL_OUTCOME_UNKNOWN` | A dispatched result cannot be confirmed or represented safely as JSON; reconcile business state first |
| `MCP_SERVER_UNAVAILABLE` | The MCP server is unavailable; follow `retryable` after restoring it |
| `REQUEST_CANCELLED` | The call was cancelled; cancelling after dispatch does not guarantee rollback at the target |
| `SERVICE_RESTARTED` | The child-to-host channel was replaced; obtain tools and state again |

When nobody can approve Node `request(names)`, it rejects with `TOOL_APPROVAL_REQUIRED` and attaches a `permissions` snapshot for display. With only `tool:call` switched off, `request()` succeeds with every name mapped to `deny` and shows no prompt; this differs from a rejected `call()`. An MCP result with `isError: true` is a tool-reported business failure, not a rejected Promise.

See [Node API](https://agent.minimax.io/docs/miniapp/reference/node-api.md#tools) for signatures and result unions.

## Agent API

Node reads `error.code`, `error.retryable`, and possibly `error.reason` with `BUSY`. Pages read `Error.message`; this table is the host mapping, not a lowercase transformation of Node names.

| Node `code` | Page `message` | Meaning and handling |
| - | - | - |
| `NOT_PERMITTED` | `not_permitted` | Required `session.run` / `session.read` missing, switched off, or not authorized for this operation; the two grants do not imply one another |
| `BUSY` | `busy` | A busy session, full queue, start-rate limit, or full observer set; Node distinguishes the reasons below |
| `SESSION_NOT_FOUND` | `session_not_found` | The session does not exist, is not owned by this Mini App, or is not visible; do not bypass ownership |
| `INVALID_ARGUMENTS` | `invalid_request` | Invalid arguments, model, target combination, or questionnaire answers |
| `AGENT_UNAVAILABLE` | `runtime_unavailable` | The operation could not start, or a read/observation is unavailable; follow Node `retryable` |
| `REQUEST_CANCELLED` | `cancelled` | Cancelled before dispatch; cancellation after a turn starts usually returns `status: 'aborted'` |
| `AGENT_OUTCOME_UNKNOWN` | `result_unknown` | A turn or write may have occurred; do not resend automatically |
| `REQUEST_NOT_FOUND` | `request_not_found` | The approval or questionnaire does not exist, was already answered, or is outside the caller's answer scope |

Node `BUSY.reason` is `session_busy`, `queue_full`, `rate_limited`, or `observer_limit`. `whenBusy` handles follow-ups to busy sessions, not other limits. Pages may also receive `busy` for a duplicated in-flight `requestId`; do not rely on an attached page `reason`, because the bridge only guarantees the error message.

Page transport failures also depend on the method: bridge failures for `run`, `answer`, `reply`, `open`, `models`, `agents`, and `create` may yield `result_unknown`; failures for `observe`, `sessions`, and `session` yield `runtime_unavailable`. Not every read-only method uses the same transport error.

See [Agent API](https://agent.minimax.io/docs/miniapp/reference/agent-api.md) for methods, returned `error` fields, and events. A fulfilled `run()` with `status: 'error'` differs from a rejected Promise; handle result status as well as `catch`.

## Page APIs

Pages do not read Node `code`, `retryable`, or `disposition`. The following codes are thrown or rejected `Error.message` values. `capabilities.has()` is synchronous and returns a boolean; see [Capability detection](https://agent.minimax.io/docs/miniapp/reference/errors.md#capabilities).

### message.append

| `message` | Meaning and handling |
| - | - |
| `user_cancelled` | The user cancelled confirmation; nothing was appended, and do not immediately prompt again |
| `invalid_request` | The argument is not a string or the request is malformed |
| `text_too_large` | More than 100,000 UTF-16 code units; shorten the text |
| `not_allowed` | The page identity or operation is not allowed |
| `target_unavailable` | The target is not writable, was deleted, or is unavailable; no fallback to another draft |
| `result_unknown` | Text may have been appended; inspect the target input before repeating |

### Window handle

The table describes v3.1.10 window behavior. Differences in v3.1.9 are noted below it.

| `message` | Meaning and handling |
| - | - |
| `invalid_request` | Invalid patch field, numeric range, or listener type |
| `inline_mode` | The page is in the file panel and this action needs a standalone window |
| `not_permitted` | Missing user gesture, a requested window capability exceeds the manifest grant, or the updated window does not overlap one display's work area by at least 40 px on both axes |
| `busy` | This page already has a transfer confirmation, mode switch, or rebuild in progress, or the same host window is confirming another Mini App's transfer; wait for the current operation to finish |
| `result_unknown` | Page identity, response, or transport cannot be confirmed; reconcile with `getState()` |

`not_found` is an internal window response and is not exposed as a page code; the page receives `result_unknown`. See [Client API](https://agent.minimax.io/docs/miniapp/reference/client-api.md#window) for methods and writable fields.

In v3.1.10, cancelling confirmation for a transfer that rebuilds the page resolves `update()` with the current state and the original `mode`, without `user_cancelled` or `busy`; inspect the returned `mode`. Active page requests or subscriptions no longer block a transfer by themselves. After confirmation, they are cancelled or cleaned up when the old page ends. Promises and listeners from the old document do not survive; see [Page rebuilds and confirmation](https://agent.minimax.io/docs/miniapp/reference/client-api.md#window-reload).

In v3.1.9, active requests, observation subscriptions, permission prompts, or capture can also make a transfer return `busy`. A page with a microphone grant has a separate transfer confirmation, where cancellation also returns `busy`. Do not apply the v3.1.10 cancellation rule to these older hosts.

### Tool preauthorization

| `message` | Meaning and handling |
| - | - |
| `invalid_request` | No user gesture, or the list is not 1–10 distinct valid runtime tool names |
| `not_permitted` | The calling page's identity or current permission does not permit this request |
| `approval_required` | A tool needs confirmation but no host approval prompt can be shown |
| `runtime_unavailable` | No usable Node tool session, or the host tool channel is unavailable |
| `result_unknown` | Response, timeout, or bridge outcome is unknown; read current permissions rather than treating an old snapshot as a grant |

With only `tool:call` switched off, page `tool.request()` succeeds with all names mapped to `deny`; it does not reject with `not_permitted`. Unlike Node's method, page failure exposes only the code. Do not depend on `error.permissions`, even if the host response contained a snapshot. See [Client API](https://agent.minimax.io/docs/miniapp/reference/client-api.md#tool-request).

### Speech transcription

| `message` | Meaning and handling |
| - | - |
| `invalid_request` | Invalid input, exact format, sample bytes, or encoded container; convert to the required PCM first |
| `not_permitted` | Microphone undeclared, switched off, or caller is not a managed Mini App page |
| `audio_too_large` | More than 16,000,000 bytes or the host transcription duration limit |
| `busy` | Another transcription from this plugin is in flight; wait for it to end |
| `runtime_unavailable` | Host speech recognition disabled, no sign-in, or a session could not be established |
| `transcription_failed` | Upstream failure, transcription deadline, or page lifecycle ended; the deadline is currently 180 seconds |
| `result_unknown` | Response or bridge failure; the page has no handle for resuming the original request |

Transcription returns text and does not cancel or stop the page's capture stream. See [Client API](https://agent.minimax.io/docs/miniapp/reference/client-api.md#speech) for format, results, and `onPartial`. Standard microphone and camera capture errors, such as `NotAllowedError`, come from the browser API rather than this transcription table.

### Camera and system notifications

These capabilities are officially supported from MiniMax Code v3.1.9. They use standard browser APIs and have no additional host error codes.

If `getUserMedia()` fails, read the browser exception's `name`, such as `NotAllowedError`. Handle notifications through the standard `Notification` API: check `Notification.permission` and the result of `requestPermission()`, and listen for the notification object's `error` event. Actual display also depends on system notification settings. Do not interpret these results as the speech transcription error codes above. See [Page device APIs](https://agent.minimax.io/docs/miniapp/authors/client-api.md#devices) for declarations and usage.

### Capability detection

`capabilities.has(name)` synchronously returns `boolean`; an unknown name returns `false`. It has no host error code or rejected Promise. Older hosts may omit the object, so check with optional chaining. Calling a missing object produces a JavaScript error, not a Mini App permission failure. See [Client API](https://agent.minimax.io/docs/miniapp/reference/client-api.md#capabilities) for names and surfaces.

## Startup and runtime diagnostics

`inspect` exposes `diagnostics.failure.code`, `diagnostics.run.failure.code`, and log `code` fields for runtime investigation. They are different layers from the lifecycle tool's `error.code` and `diagnostic.reasonCode`. For example, a low-level `READINESS_TIMEOUT` helps locate listener/readiness problems, while the public publishing diagnostic uses `RUNTIME_NOT_READY`.

Check that the entry exports `start(context)`, binds the assigned port with `node:http`, and returns after the listener and routes are installed. Keep missing exit, time, and failure details unknown; a diagnostic name alone does not prove process exit. See [Node API](https://agent.minimax.io/docs/miniapp/reference/node-api.md#lifecycle), [Port authentication](https://agent.minimax.io/docs/miniapp/authors/node-runtime.md#auth), and [Publishing and troubleshooting](https://agent.minimax.io/docs/miniapp/authors/publish.md).
