Errors
Thirteen codes. Each one has fixed copy in the widget.
Failures arrive as AgentError from actionwire, with a code field, or as a ToolResult with ok: false and a code.
import { AgentError } from 'actionwire';
try {
await assistant.send('delete everything');
} catch (error) {
if (error instanceof AgentError && error.code === 'BUSY') {
// A turn is already running.
}
}Codes
| Code | Shown to the person | Cause |
|---|---|---|
UNSUPPORTED_WEBMCP | This browser does not support WebMCP. | document.modelContext is absent, incomplete, or not a secure context. |
DISCOVERY_FAILED | The assistant could not read the tools on this page. | getTools() threw, or returned something that is not a list. |
INVALID_SCHEMA | A tool definition is not valid. | A schema is not an object, or its dialect is unsupported. |
TOOL_UNAVAILABLE | This tool is not available. | The chosen tool is not in the current list. |
STALE_TOOLS | The tool list changed. Try again. | The revision moved after planning or after the prompt appeared. |
INVALID_ARGUMENTS | The tool input is not valid. | Model arguments failed schema validation. |
EXECUTION_FAILED | The tool failed. | The handler threw, or returned a result that is not JSON. |
CONFIRMATION_DENIED | The action was cancelled. | A person selected Cancel, or pressed Escape. |
ABORTED | The assistant was cancelled. | cancel(), clear(), or dispose() ran. |
TIMEOUT | The assistant timed out. | The model call or a tool call passed timeoutMs. |
MODEL_ERROR | The assistant could not complete the turn. | The model endpoint failed or returned an unusable body. |
TURN_LIMIT | The assistant reached the turn limit. | The model asked for more than maxRounds rounds. |
BUSY | The assistant is busy. | send() ran while a turn was already going. |
Which ones end the turn
BUSY rejects the send() promise and changes nothing. CONFIRMATION_DENIED, TOOL_UNAVAILABLE, INVALID_ARGUMENTS, EXECUTION_FAILED, and STALE_TOOLS become a failed tool result: the model sees them and can try something else in the same turn.
The rest end the turn and land in state.error.
Tool results never throw
A tool that fails returns a ToolResult with ok: false, a code, and a text the model can read. The turn continues. This is intentional, so a model can recover from one bad call without losing the conversation.
Result size
A tool result is capped at 8192 characters of text. Longer text is cut. A result whose JSON exceeds that size keeps its text summary but drops the structured data field.