On this page

Errors

This page is the whole set, and the place to look when you want to handle errors once rather than per call. A tool page lists only what is specific to that tool, and links back here for the rest.

The common set

Seven classes are reachable from every tool, because every call runs the same lifecycle: AuthError, ForbiddenError, ValidationError, PolicyDenied, QuotaExceeded, UpstreamError and TimeoutError. Handle those once. What varies from tool to tool is only:

ClassReachable from
NotFoundtools that take an id or a name that must already resolve to an object
ApprovalRequiredthe 32 tools marked consequential, which a policy may hold for a person; the project's write gate (on by default) also holds the 31 that write (all but query-context) when an API key or SDK session calls them
ConfigurationErrorthe 56 plane-gated tools; the six always-registered tools cannot reach it

Each tool page's error table is that tool's slice of the three.

How an error is chosen

The gateway answers a refused call with an error string and an HTTP status. Both SDKs turn that pair into a typed exception, choosing on the error string first and the status second, so the same refusal becomes the same class in both languages.

On REST and on the Wexa MCP server there is no typed error: REST gives you the status and the error / error_description pair directly, and the MCP server reports a refusal as a JSON-RPC error or as isError: true with the message in content[0].text.

The classes

Both SDKs share one base class, WexaError. Catching it catches everything below.

ClassStatusRaised when
AuthError401The credential is missing, malformed or revoked.
ForbiddenError403The credential lacks the grant this tool needs, or its scope does not cover the project.
PolicyDenied403A policy rule refused this specific call. Subclasses ForbiddenError, so catching that catches this too. The refusal names the rule.
ValidationError400 / 422An argument is missing, of the wrong type, or is one the platform binds itself. Also raised client-side, before any request, for a server-bound argument.
ApprovalRequired202A person must approve this call before it runs. Carries the approval id.
ApprovalError—The approval was rejected, or the wait for it failed.
QuotaExceeded429The project or organization is over its request rate or its credit balance.
NotFound404An id in the arguments matches nothing in this project.
ConflictError409The change collides with the object's current state.
UpstreamError5xxA service behind the gateway failed or was unreachable.
ConfigurationError5xxThe tool is not available to you. Retrying will not help.

Where the two SDKs differ

The classes are not quite identical, and code that catches by name has to account for it.

TypeScriptPython
TimeoutTimeoutErrorTimeoutError_ — the trailing underscore avoids shadowing Python's builtin, and it subclasses UpstreamError rather than standing alone
Transport failureTransportErrorno equivalent; a transport failure surfaces as UpstreamError
Total classes13 plus WexaError12 plus WexaError

Reading an error

Both SDKs attach the governance ids to the exception, and they are the fastest way to find out why a call was refused.

ValidationError: malformed after_id "<after_id>": expected a table_id from a previous page
[lifecycle_id=qlc_000050 trace_id=a43def45c69440ac982ecd49b4396df1]

The lifecycle_id is the handle to the audit record for the call. Quote it when asking why something was allowed, refused or held.

See also

The tool index for the tools themselves.