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

# Error Handling

> How the MPC SDK reports failures, the error categories you can branch on, and practical ways to recover with retries and input checks.

When a signing call fails, the SDK gives you a clear, human-readable message and a category you can branch on. The same categories drive both runtimes. Wrap each call, read the message, and act on it.

## The error model

Node and Python surface failures differently, and that difference is the most useful thing to know.

* **Node** throws a generic `Error`. The category prefix appears at the start of the message string, so catch the one exception type and read the message to decide what to do. For example: `err.message.startsWith("Rejected:")` or `err.message.startsWith("Signing service:")`.
* **Python** maps the same failures onto two built-in exceptions. `ValueError` means fix the call (invalid input or encoding). `RuntimeError` means retry or check connectivity (signing service, transport, or an incomplete request).

<CodeGroup>
  ```js errors.js theme={null}
  try {
    const rawTx = await client.signEvm1559(
      wallet, 8453, 0, "0xRecipientAddress",
      "1000000000000", "1000000000", "2000000000", 21000
    );
  } catch (err) {
    // Node throws a generic Error. The category is in the message.
    console.error(err.message);
  }
  ```

  ```python errors.py theme={null}
  try:
      raw_tx = client.sign_evm_1559(
          wallet, 8453, 0, "0xRecipientAddress",
          1_000_000_000_000, 1_000_000_000, 2_000_000_000, 21_000,
      )
  except ValueError as err:
      # Caller mistake: invalid input or encoding. Fix the call.
      print("rejected:", err)
  except RuntimeError as err:
      # Infrastructure: signing service or transport. Retry or check connectivity.
      print("signing failed:", err)
  ```
</CodeGroup>

<Note>
  Logging the message is the fastest way to see which category you hit. In Python, the exception type already tells you which half you are in.
</Note>

## Error categories

Use this table to map a failure to a fix.

| Category            | What it means                                                                                                                   | How to fix                                                                                                                                                                     |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **InvalidInput**    | An argument was malformed or out of range, like a bad chain id, a malformed wallet, or a value that is not a base-unit integer. | Check the arguments. Pass the wallet from `createWallet` and confirm the chain identifier against [One wallet, every chain](/mpc/curves).                                      |
| **Rejected**        | The request was not allowed.                                                                                                    | Check your inputs and arguments, then retry.                                                                                                                                   |
| **Signing service** | The signing service could not complete the request. This includes authentication failures and unexpected service failures.      | Retry with backoff. Confirm your endpoint and that your API key is valid. See [credentials and authentication](/getting-started/prerequisites/credentials-and-authentication). |
| **Transport**       | The network call to the signing service failed, like a timeout, DNS issue, connection refused, or TLS error.                    | Retry with backoff. Check network reachability to your endpoint. See [Timeouts](#timeouts) below.                                                                              |
| **Protocol**        | The signing exchange did not complete.                                                                                          | Retry the whole call from the start. Do not reuse partial state.                                                                                                               |
| **Encoding**        | The SDK could not serialize or deserialize a value, like a malformed wallet blob, a bad hex field, or an unparseable amount.    | Confirm you are passing back the exact wallet blob you stored. Check hex fields and amount encoding (decimal strings in Node, native `int` in Python).                         |

<Tip>
  In Python, **InvalidInput**, **Rejected**, and **Encoding** surface as `ValueError`. **Signing service**, **Transport**, and **Protocol** surface as `RuntimeError`. In Node all six surface as a generic `Error`.
</Tip>

<Note>
  If `signEvm7702` refuses with an **InvalidInput** failure and every argument you passed looks correct, contact [support@walletsuite.io](mailto:support@walletsuite.io). This can happen if your account is not yet set up for the batched signing path.
</Note>

## Timeouts

Every signing call and wallet creation needs your endpoint reachable for the round trip. One setting governs how long the client waits.

* **`registerTimeoutSecs`** (default `30`) sets how long the client waits while connecting before it gives up. Raise it for high-latency networks. Lower it to fail fast in a tight request path. It is a constructor argument, positional in Node and `register_timeout_secs=` in Python.
* **Reachability.** If your environment cannot reach your endpoint, you get a **Transport** failure. Confirm outbound network access to the URL you passed. The recommended production endpoint is `https://cosigner.walletsuite.io`.

<CodeGroup>
  ```js timeout.js theme={null}
  const { MpcClient } = require("@walletsuite/wallet");

  const client = new MpcClient(
    "https://cosigner.walletsuite.io",
    process.env.WALLETSUITE_API_KEY,
    60 // registerTimeoutSecs (default 30)
  );
  ```

  ```python timeout.py theme={null}
  import os
  import walletsuite_wallet as ws

  client = ws.MpcClient(
      "https://cosigner.walletsuite.io",
      api_key=os.environ["WALLETSUITE_API_KEY"],
      register_timeout_secs=60,  # default 30
  )
  ```
</CodeGroup>

<Note>
  A timeout surfaces as a **Transport** failure, which is a `RuntimeError` in Python. Retry with backoff once the network is healthy. A retried call starts fresh, so no partial state carries over.
</Note>

## Retrying

Most failures are recoverable.

* **Retry with backoff** on **Signing service**, **Transport**, and **Protocol** failures. These are transient. Start fresh on each attempt and do not reuse partial state.
* **Fix the call** on **InvalidInput** and **Encoding** failures. Retrying the same arguments will fail the same way, so correct the input first.
* **Check inputs, then retry** on a **Rejected** failure. Confirm your arguments are right for the request you intend, then try again.

A retried call is always a clean run. You can wrap your signing calls in a small retry helper that backs off on the `RuntimeError` categories and surfaces the `ValueError` categories straight to your own validation.

## Next steps

<CardGroup cols={2}>
  <Card title="SDK reference" icon="book" href="/mpc/sdk-reference">
    The full client surface, methods, and arguments across Node and Python.
  </Card>

  <Card title="Signing" icon="signature" href="/mpc/signing">
    Sign transactions across 84 chains from one wallet, with shared prose and per-language code.
  </Card>
</CardGroup>
