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_PRIVKEYis 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.
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: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 withgetJsonRpcFullnodeUrl("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.
Open an issue
Anything not covered here, file it on GitHub or DM on X.