# Troubleshooting

Use the response `code` to identify the condition. Messages provide context for people; codes are intended for application logic.

## `403 ORIGIN_NOT_ALLOWED`

Check that the request's origin exactly matches one registered for the key. Include staging, local ports and preview hostnames. Wildcards are not supported; a fixed preview hostname can simplify configuration.

Browser keys also require the `Origin` header. For backend calls or MCP, use a server-side `gm_live_` key. See [keys and origins](https://docs.deads.io/guides/keys.md).

## `403 COLLECTION_NOT_IN_SCOPE`

Confirm that the identifier belongs to a collection assigned to your key. The same response is used for unknown and inaccessible collections, so check for typing errors as well. A key without assigned collections has no collection access.

## `403 SANDBOX_KEY_ON_MAINNET` / `LIVE_KEY_ON_TESTNET`

Match the key to the network. Use `gm_test_` for test-network collections and a production key for production collections.

## `404 COLLECTION_NOT_FOUND` on an id you know exists

Check the short ID, UUID or on-chain address and confirm the collection is available through your key. Preserve address case. If using an older API deployment, verify its supported identifiers against the SDK version.

## The price is wrong, or shows 0

Read `priceDisplay` and handle all four `kind` values. Show “Free” only for `kind: 'amount'` with `isFree: true`. A pegged display price can be approximate. Use `peggedPrice(phaseId)` to refresh it; v1 phases do not expose a raw `price` field. See [pricing](https://docs.deads.io/concepts/read-model.md#pricing-%E2%80%94-a-union-never-a-number).

## “Mints remaining” differs between responses {#mints-remaining-is-wrong-for-some-wallets}

Use `walletMints` for minted and remaining counts. It includes bonus mints; eligibility evaluates allocations with different counting rules. Refresh wallet data after a mint.

## `CLIENT_BROADCAST_NOT_ALLOWED`

Send the signed transaction bytes as `signedTransaction`. GraveMint submits the transaction; `execute` does not accept a client-submitted `transactionHash`. See [wallets and signing](https://docs.deads.io/guides/signing.md).

## `TX_MODIFIED`

The signed transaction differs from the prepared transaction. Check that the wallet adapter only signs the supplied bytes and does not add instructions or change accounts. Do not resubmit the same modified transaction. Correct the adapter and prepare a new session.

## `SESSION_EXPIRED`, or a mint that 409s

An expired session needs a fresh `prepare`. A conflict such as `ALREADY_PROCESSING` or `ALREADY_COMPLETED` requires checking the existing session's outcome before starting another mint. Keep these cases separate: a request that is already processing may still complete.

## Batch result handling {#err-code-is-undefined-on-a-failed-mint}

`mint()` can return a partial batch outcome without throwing. Inspect `results[]`, including each transaction's `errorCode` and `pending` state. With `executeBatch()`, top-level `success` means at least one transaction succeeded; it does not mean all succeeded.

```ts
const result = await gm.mint.mint({ collectionId, phaseId, walletAddress, quantity, signer });
if (result.results) {
  for (const transaction of result.results) {
    if (transaction.pending) {
      // Retain transaction.sessionId and check the wallet before retrying.
    } else if (!transaction.success) {
      // Display transaction.error and handle transaction.errorCode.
    }
  }
}
```

For `MintOutcomeUnknownError` / `OUTCOME_UNKNOWN`, retain `sessionIds` and check the wallet. Do not automatically submit a new mint while the outcome remains uncertain.

## `429`, or mints are throttled

Honor `Retry-After` and review the [rate limits](https://docs.deads.io/guides/keys.md#rate-limits). Prepare and execute share a per-key limit, and prepares also use a collection limit shared with the hosted site.

The SDK retries eligible read requests with backoff. Execute calls are not retried automatically by default, because the original transaction may already have been submitted. See [SDK retries](https://docs.deads.io/sdk/gravemint.md#errors-and-retries).

## `503 AUTH_UNAVAILABLE`

The authentication service could not complete the key check. Retry with backoff; this response does not mean the key is invalid. `LOOKUP_FAILED` similarly indicates that a collection lookup could not complete.

## Browser CORS errors {#nothing-appears-in-your-network-tab-at-all}

Inspect the preflight (`OPTIONS`) response in the network panel. If the browser rejects that response, it will not send the subsequent API request. A `204` status alone is insufficient: check that `Access-Control-Allow-Origin` matches the requesting origin and that the requested headers and method are allowed.

## Still stuck

Include the error code, key prefix (`gm_pub_`, `gm_live_` or `gm_test_`), origin, collection identifier and SDK version when contacting support. Include a sanitized response where useful. Do not send the full key.

---
Source: https://docs.deads.io/guides/troubleshooting
Markdown: https://docs.deads.io/guides/troubleshooting.md
