> For the complete documentation index, see [llms.txt](https://docs.ipor.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipor.io/build-on-fusion/developer-guide/common-errors.md).

# Common Errors

Revert selectors and the role table for the errors most likely to block a Fusion vault deployment.

Revert selectors and setup errors an agent or developer is likely to hit while deploying or operating a Fusion vault (see Deploy your first Fusion vault), with the cause and the fix for each. Same table as `fusion://invariants` on the MCP server and the SDK README, kept in sync with both.

### Revert table

| Selector                                                    | Revert                               | What happened                                                                                                                                                                                                  | Fix                                                                                                                                                                                                         |
| ----------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0x8745fbfd`                                                | `DaoFeePackagesArrayEmpty()`         | `clone()` was sent to `IporFusionFactoryImpl`                                                                                                                                                                  | Send it to `IporFusionFactoryProxy` for that chain — see Addresses                                                                                                                                          |
| `0x9996b315`                                                | `AddressEmptyCode(address)`          | `execute()` touched a market with no balance fuse                                                                                                                                                              | `add_balance_fuse(market_id, balance_fuse)` before the first `execute` on that market                                                                                                                       |
| `0x068ca9d8`                                                | `AccessManagedUnauthorized(address)` | The caller lacks the role the function requires: `FUSE_MANAGER` for `add_fuses`, `grant_market_substrates`, `add_balance_fuse`; `ALPHA` for `execute`; `WHITELIST` for `deposit` and `mint` on a private vault | `AccessManager.grant_role(role, account, 0)` from the role's admin (`OWNER` grants `ATOMIST`, `ATOMIST` grants the rest); for a reverting `deposit`, whitelist the depositor or convert the vault to public |
| `ValueError: Private key required for sending transactions` | SDK, before any transaction          | `.send()` on a `Web3Context` without a key                                                                                                                                                                     | `Web3Context(w3, chain_id, signer=..., private_key=...)` or `Web3Context.from_url(url, private_key=...)`                                                                                                    |

### Role table

| Role                | ID  | Grants                                                                             | Granted by                                   |
| ------------------- | --- | ---------------------------------------------------------------------------------- | -------------------------------------------- |
| `OWNER_ROLE`        | 1   | Everything below, via the access manager                                           | Set at vault creation (the `clone()` caller) |
| `ATOMIST_ROLE`      | 100 | Vault configuration authority; administers `FUSE_MANAGER`, `ALPHA` and `WHITELIST` | `OWNER`                                      |
| `ALPHA_ROLE`        | 200 | Can call `execute`                                                                 | `ATOMIST`                                    |
| `FUSE_MANAGER_ROLE` | 300 | Can call `add_fuses`, `grant_market_substrates`, `add_balance_fuse`                | `ATOMIST`                                    |
| `WHITELIST_ROLE`    | 800 | Can `deposit` / `mint` into a private vault                                        | `ATOMIST`                                    |

A fresh clone grants the owner only `OWNER_ROLE` — every configuration and `execute` call from that account reverts `AccessManagedUnauthorized` until `ATOMIST_ROLE` is granted first (it administers the rest), matching step 2 of Deploy your first Fusion vault.

### Related invariants

* Clone from `IporFusionFactoryProxy`, never from `IporFusionFactoryImpl` — only the proxy carries the fee configuration.
* Register all three of `add_fuses`, `grant_market_substrates` and `add_balance_fuse` before the first `execute` on a market. Any order between them works; what is not optional is that all three precede `execute`.
* A fresh clone is private: `deposit` and `mint` revert until either the depositor holds `WHITELIST_ROLE` (keeps the vault private) or an Atomist calls `convert_to_public_vault()` (opens deposits to every address, and cannot be reverted).
* Fuses are immutable and addresses are per chain — resolve `(chain, name)` in [`ipor-abi`](https://github.com/IPOR-Labs/ipor-abi); never reuse an address across chains.
