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

# Troubleshooting

> What goes wrong on first run with @altheia-xyz/sui, and what to do.

The things that trip up a first integration on Sui testnet. If you hit something not here, ping the team on X [@altheiaxyz](https://x.com/altheiaxyz).

## `no AgentCap owned by <address>`

`agentRefs` reads the `AgentCap` the agent key owns and derives the vault, policy, and cap from it. This error means the address owns no cap. Two causes:

* **Wrong key.** The `AGENT_PRIVKEY` is not the key the agent was provisioned for. The cap is delivered to a specific address at provision time.
* **Not provisioned.** The agent was never created, or the provisioning transaction did not land. Provision it in the dashboard.

The `AgentCap` is non-transferable, so it always lives at the address it was minted to.

## A swap is denied, but I expected it to pass

Decode the abort to see why:

```ts theme={null}
const ab = decodePolicyAbort(e);
console.log(ab?.reason_code);
```

| `reason_code`         | Check                                                         |
| --------------------- | ------------------------------------------------------------- |
| `over_per_tx_cap`     | Amount exceeds `per_tx_cap`. Read it with `readPolicyObject`. |
| `over_per_day_cap`    | The rolling 24h total would exceed `per_day_cap`.             |
| `package_not_allowed` | The pool isn't in `allowed_packages`.                         |
| `action_not_allowed`  | `deepbookSwap` isn't in `allowed_actions`.                    |
| `policy_expired`      | `expires_at_ms` has passed.                                   |
| `agent_paused`        | The owner paused the agent. Unpause to resume.                |
| `policy_revoked`      | The owner revoked the agent. Terminal — provision a new one.  |

## A swap "failed" but `decodePolicyAbort` returns null

That is not a policy decision. `decodePolicyAbort` only decodes aborts from the `policy` module; it returns `null` for everything else. The common non-policy failure is DeepBook: a thin testnet book can fill zero, or the pool can lack liquidity at your price. Surface the raw error rather than treating it as a denial. `guardedSubmit` does this — it returns `{ ok: false }` with no `reason_code` for a non-policy failure.

## Allowed, but nothing seemed to trade

The swap is a policy decision, not a guaranteed fill. `allowed` (or `r.ok`) means the policy permitted the action and the transaction landed. On a thin testnet pool the gated DeepBook order can fill zero. Check the digest on a Sui explorer to see what settled.

## Wrong network

The deployment is on **testnet**. Construct the client with `getJsonRpcFullnodeUrl("testnet")` and set your wallet to Testnet. The `SUI_TESTNET` ids resolve only on testnet.

## Sequential actions race on object versions

`keypairExecutor` waits for finality after each submit so the next transaction from the same key doesn't read a stale gas coin or object version. If you sign without it, space out transactions or wait for each digest before sending the next.

## Owner operation fails: needs `refs.ownerCap`

`revoke`, `pause`, and `killAndDrain` are signed with the `OwnerCap`. The refs from `agentRefs` carry an empty `ownerCap` (it derives from the agent key, which has no owner authority). Build owner-side refs with the `OwnerCap` id and the owner key. In the dashboard, the owner wallet holds the cap and these are one click.

<Card title="Open an issue" icon="github" href="https://github.com/altheia-xyz/altheia-sui" horizontal>
  Anything not covered here, file it on GitHub or DM on X.
</Card>
