> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://sdk.railnet.org/api/mcp` to find what you need.

# Errors

`getRailnetError` decodes a Railnet revert out of whatever viem threw. [Handling reverts](/guides/handlingReverts) shows where it sits in a call.

## Import

```ts twoslash
import { getRailnetError, protocolErrorsAbi, railnetErrorHints } from '@railnetorg/railnet-sdk'
```

## Usage

```ts
import { getRailnetError } from '@railnetorg/railnet-sdk'

const reverted = getRailnetError(error)
```

## Returns

`RailnetError | null`

`null` for a failure that was not a contract revert, such as a rejected signature, a transport
error or a gas estimation failure.

### name

* **Type:** `string`

The custom error's name as the contract declares it, such as `MissingRole` or `InvalidQuerySalt`.

### args

* **Type:** `readonly unknown[]`

Its decoded arguments, in declaration order. `MissingRole` carries `[role, scope, caller]`, so the
role that was missing and the scope it was checked against are both in hand. Empty for an error
that takes none.

### hint

* **Type:** `string | undefined`

What to do about it, when this package knows. `undefined` means the name already says what happened.

### cause

* **Type:** `ContractFunctionRevertedError`

The viem error this was read from, for the raw data and the full message.

## protocolErrorsAbi

Every custom error the protocol declares, on one ABI fragment. `getRailnetError` falls back to it
for a revert the call's own ABI does not carry. Hand it to `decodeErrorResult` to decode one
yourself.

## railnetErrorHints

The hint table itself, keyed by error name. Useful to render a whole error map in an operator UI,
or to check coverage:

```ts twoslash
import { railnetErrorHints } from '@railnetorg/railnet-sdk'

railnetErrorHints.MissingRole
// 'The caller lacks the role for that scope. Scope a grant to the contract that performs the
//  gated call. MULTI_VEHICLE_SET_QUEUES goes to the queue strategy engine, not to the multi
//  vehicle. Check with getHasRole first.'
```

Only the errors whose name alone leaves a caller guessing have an entry.

## The ones that catch people

| Error | Why it fires |
| :--- | :--- |
| `MissingRole` | The grant was scoped to the multi vehicle instead of the engine that performs the check. |
| `InvalidQuerySalt` | The call was built for one `sender` and sent by another. A Safe, a batch or a relayer is the sender, not the user. |
| `InvalidOutput` | The query names an output asset the vehicle will not produce. A DEPOSIT must name the vehicle, a REDEEM its underlying asset. |
| `InvalidEstimation` | The `minOutput` floor was not met. The second argument is what the vehicle would actually produce. |
| `InsufficientAllowance` | The factory or conduit was never approved. For a spawn the amount comes from [`getInitialDepositAmount`](/actions/getInitialDepositAmount). |
| `AssetNotAuthorized` | The AssetRegistry has nothing registered for that asset, so no factory will spawn against it. |
| `MinOutputRequiresPinnedAmount` | A dispatch combined `minOutput` with `maxUint256`. |
| `StateUnchanged` | The write re-sends the values already stored. |
