---
description: "An error to throw from a tool's execute to pick the code the agent gets."
---

# `WebToolError`

An error to throw from a tool's `execute` to pick the code the agent gets. Without it, a thrown error is coded `failed`; with it the agent can tell bad input from a missing page from a person who must decide.

## Import

```ts
import { WebToolError } from "@webmcp-agents/core";
```

## Example

A lookup that tells the agent its input was wrong, so it can fix the reference and retry.

```ts title="tools/get-booking.ts"
import { defineWebTool, WebToolError } from "@webmcp-agents/core";
import { z } from "zod";

const bookings = new Map([["SK-7F3K2Q", "LHR to JFK, 9 Dec, 08:15"]]);

export const getBooking = defineWebTool({
  id: "get_booking",
  title: "Look up a booking",
  description:
    "Look up a confirmed booking's itinerary by its reference " +
    "(SK-…). Use after booking, from any page.",
  inputSchema: z.object({
    reference: z.string().describe("e.g. SK-7F3K2Q"),
  }),
  readOnly: true,
  execute: ({ reference }) => {
    const found = bookings.get(reference.toUpperCase());
    if (!found)
      throw new WebToolError(
        "invalid_input",
        `No booking ${reference.toUpperCase()}. Check the reference.`,
      );
    return found;
  },
});
```

The agent gets `Error [invalid_input]: No booking SK-0000. Check the reference.`, with `structuredContent.error` set to `{ code: "invalid_input", retryable: true }`.

## Options

`new WebToolError(code, message)`.

| Name | Type | Default | Description |
|---|---|---|---|
| `code` | `ToolErrorCode` | required | Why the call failed: `cancelled`, `interrupted`, `timeout`, `unavailable`, `invalid_input`, `needs_user` or `failed`. See the table under [`toolError`](/docs/reference/core/tool-error#error-codes). Readable afterwards as `error.code`. |
| `message` | `string` | required | What the agent reads. Say what to do next: "No booking SK-0000. Check the reference." beats "Not found". |

## Returns

An `Error` subclass with `name` `"WebToolError"` and the readonly property `code: ToolErrorCode`.

## Notes

- [`errorResult`](/docs/reference/core/error-result) uses the error's `code` over its own default, so the code survives [`toModelContextTool`](/docs/reference/core/to-model-context-tool) and reaches the agent.
- [`useWebTool`](/docs/reference/react/use-web-tool) and [`defineWebTool`](/docs/reference/core/define-web-tool)'s `invoke` reject with a `WebToolError` carrying the agent's code, so your own UI can branch on `error.code`.
- An abort (`AbortError`) is never wrapped: a cancelled call stays a cancellation.

## See also

- [Errors](/docs/concepts/errors), the codes and when to use each
- [`toolError`](/docs/reference/core/tool-error), the result it becomes
- [`errorResult`](/docs/reference/core/error-result), how a thrown value is turned into a result
- [`defineWebTool`](/docs/reference/core/define-web-tool), where `execute` lives
