Skip to content

Arete documentation

Errors and refusals

For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending .md to the URL or sending Accept: text/markdown.

For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /sandboxes/errors.md.

Every sandbox_* error carries code, retryable and a hint, even when the API could not be reached (status: 0) or something in front of it answered with no readable body. A refusal also names the rule that refused and what triggered it (program, instruction, mint, attempted, cap, remaining), and for sandbox_invoke the idempotencyKey.

  • retryable: false: the same call fails again. The hint says what to change.
  • retryable: true on a read or a preview: nothing changed. Retry the same call, after retryAfterSeconds when present.
  • retryable: true on sandbox_invoke: the action may have run unless the code says the guard refused it. Never retry it under a new key. Retrying with the same idempotencyKey is safe: the key never runs twice, and the same request returns the original result with replayed: true. Older servers answer the repeat with sandbox-duplicate-action instead, so look the action up with sandbox_action and the idempotencyKey: if it ran, don’t repeat it; if it was refused, retry with a new key; if no action has the key, retry with the same key. A replayed answer (replayed: true) is the exception: it already says what happened, as below.

A refusal with replayed: true is the recorded refusal of the action the key already ran, not a new one. Its hint says so; to try again, fix the request and use a new key.

A replayed refusal also carries rejectCode, the code on the stored action record. It can differ from the replayed code. Go by the replayed body’s code and retryable, not the record’s: a replayed upstream outage comes back with retryable: true and is not a permanent refusal, even when the record (here or in sandbox_action) reads as final. Retry it with a new key, after retryAfterSeconds when present; the same key only replays the outage.

A call that can’t tell which sandbox it is for is refused before anything is sent to a sandbox. The hint names the tools to call: sandbox_list, then sandbox_select (or a4 sandbox list and a4 sandbox use).

CodeMeaning
sandbox-selection-requiredSeveral sandboxes are granted and none is chosen; the error lists them
sandbox-none-grantedNo sandbox has been granted to this agent yet
sandbox-unknownThe sandbox argument matches no granted sandbox
sandbox-pausedEvery granted sandbox is paused
sandbox-not-configuredThe API can’t list grants (an older server): pass a sandbox id, or set ARETE_SANDBOX_ID

Refusals of reads through a sandbox (program_read_account, read_view, connect, a4 program account decode, a4 get, a4 stream). From MCP they are tool errors with isError: true; the CLI prints the code and a hint naming the matching a4 command.

CodeMeaning
sandbox-program-not-allowlistedThe program is not in the rules; programs lists the ones left out. sandbox_reads (or a4 sandbox reads) lists what can be read
sandbox-read-requiredThis API key is bound to a sandbox grant and reads only through a sandbox; sandboxes names them. Choose one, or pass it
sandbox-read-programs-unknownArete could not tell which programs the stack decodes, so a sandbox cannot read it. Read the programs’ accounts directly
sandbox-read-target-unsupportedA sandbox reads only program accounts and stack views of the programs in its rules
sandbox-reads-mainnet-onlySandbox reads cover mainnet only; this sandbox or stack runs on a dev environment
sandbox-inactiveThe sandbox is not active. Only its owner can reactivate it
CodeMeaning
sandbox-program-not-allowlisted, sandbox-guard-program-not-allowlistedThe program isn’t in the rules. Only the owner can add it.
sandbox-instruction-not-allowlisted, sandbox-guard-instruction-not-allowlistedThat instruction isn’t allowed for the program.
sandbox-guard-outflow-exceeded, sandbox-limit-per-action, sandbox-limit-windowOver a limit. Use a smaller amount; remaining says how much is left.
sandbox-rules-missing, sandbox-rules-unsignedThe owner must set or re-sign the rules
sandbox-pausedThe sandbox is paused. Only the owner can resume it.
CodeMeaning
sandbox-intent-invalid, sandbox-intent-foreign-signerNames, args or accounts don’t match sandbox_rules, or a signer other than the wallet; missingAccounts lists what’s needed and accountGuidance how to find each (Finding accounts)
sandbox-guard-trial-failedThe transaction fails when run. Check accounts and amounts; logs are in the details.
sandbox-guard-insufficient-fundsThe wallet can’t pay: balanceLamports, and shortfallLamports when known
sandbox-derive-invalidBad programId or seeds: at most 15 seeds of at most 32 bytes each
sandbox-duplicate-action, sandbox-idempotency-key-reusedThe key already belongs to an action, named by its id. Current servers send this only when a different request reuses the key: use a new key. Older servers send it for every repeat, so look the action up with sandbox_action
sandbox-request-invalidThe API rejected the request’s shape
CodeMeaning
sandbox-action-not-grantedThe owner hasn’t granted this agent that action
sandbox-grant-missing, sandbox-consent-unsignedThe owner hasn’t granted this agent access, or must grant it again
sandbox-agent-key-requiredSet ARETE_API_KEY to the agent account’s secret key, or log in as the agent
sandbox-session-invalid, sandbox-session-revoked, sandbox-session-expiredThe sandbox token stopped working and couldn’t be renewed; access may have been revoked
sandbox-unauthorized, sandbox-forbidden, sandbox-not-foundAuthentication failed, access is refused, or the sandbox doesn’t exist

These say nothing about the request itself.

CodeMeaning
sandbox-api-unreachable, sandbox-api-timeout, sandbox-api-unavailable, sandbox-internal-error, sandbox-response-unreadableThe API, or the way to it, failed. Follow the retry rule.
sandbox-guard-unavailable, sandbox-guard-timeout, sandbox-guard-incomplete, and other sandbox-guard-* infrastructure codesThe guard couldn’t check the transaction, so nothing was signed. Retry an action with a new key.
sandbox-rate-limitedToo many requests: wait for retryAfterSeconds
sandbox-response-too-largeAsk for less (a smaller limit, no includeRaw), or look an action up by key
sandbox-conflictThe request conflicts with the sandbox’s current state