Troubleshooting
When a request fails, we return an error with a stable code and a readable message. We recommend that your agent branch on the error code, since the code is the stable identifier, and not match on the message text.
If an action fails with a policy or authorization error, don't retry it unchanged. Instead, read the reasons, then either change the request or ask a person who can change the policy or approve the action (an admin).
Error format
Most API errors return the following body:
{ "error": "A readable message.", "code": "stable_code", "requestId": "..." }There are three fields in this error body:
| Field | Description |
|---|---|
error |
A message in plain English that is safe to show a person. |
code |
A stable identifier. This is null when the route doesn't set one. |
requestId |
Identifies the request. Include it when you contact support about an error. |
Errors from agent authentication are shaped differently. They put the stable
code in error and the readable text in message:
{ "error": "stable_code", "message": "A readable message." }. Your agent
should read both fields.
The CLI prints the readable message on stderr (standard error). The SDK
raises an ApiError with code, status, fields, and details.
Linking
Below are the problems you may see while linking an agent, along with the cause of each.
| Symptom | Cause | What to do |
|---|---|---|
| The link expired | 15 minutes passed before the link was approved. | Run the same catena link command, which will print a new link. |
| The person declined | The person denied the request or cancelled their approval. | Stop. Only start again if they ask you to, after running catena unlink --profile <name> --force. |
Already linked when you wanted a new agent |
The directory is already bound to a profile. | Pass --profile <new name>. |
created_out_of_window |
The machine's clock is wrong. | Fix the clock. Linking again won't help. |
client_upgrade_required |
Catena no longer accepts this CLI version. | Run npm i -g @catena/cli, then try again. |
| The agent has as many linked clients as allowed | The agent reached the signing provider's limit on linked clients. | Unlink one of the agent's machines, or revoke one of its secret keys. |
| A keychain write is refused | A sandboxed tool (e.g., Codex's default sandbox) blocks writes to the keychain. | Approve the sandbox's escalation, or use a secret key. |
Linux Secret Service credential operation failed |
A CLI older than 0.17 is running on a Linux host with no keyring. | Upgrade the CLI. Current versions store the key in a file instead. |
Signing and authentication
| Code | Cause | What to do |
|---|---|---|
| Catena rejected this machine's signing key | The machine was unlinked, or its key was revoked. | Run catena link again. |
The error names CATENA_SECRET_KEY |
The secret key was revoked or is wrong. | Create a new key in the console and set the variable again. Don't run link. |
missing_auth, missing_signature_headers, unsupported_signature_profile |
A proxy between the agent and Catena changed or removed the signature headers. | Make sure the proxy keeps all four Catena-* headers, the URL, and the body. Note that a new key won't fix this. |
signature_auth_disabled |
The API you're calling doesn't accept signed requests. | Check the API URL. |
| "Local signer public key does not match" | Catena holds a different wallet key for this link. | Run catena unlink --profile <name>, then catena link <agent-id> --profile <name>, and approve the new link. |
Payments
Below are the errors your agent may receive when it sends a payment. Where an error carries an HTTP status, it is shown in parentheses.
| Code | Cause | What to do |
|---|---|---|
rail_method_mismatch |
The method doesn't match the rail. | Use ach or wire for a bank rail, and on-chain for a wallet rail. See Send wires and ACH. |
policy_send_account_required (400) |
The policy allows several source accounts, and the request didn't name one. | Pass --account. |
policy_send_account_unavailable (403) |
The policy allows no source account for this send. | Ask an admin to check the policy. |
movement_wallet_approval_open (409) |
Another payment from the same wallet is being approved or signed. Nothing moved. | Wait until details.heldUntil, or a few seconds when it's null, then send again. Use a new idempotency key when details.intentCancelled is true, and the same key when it's false. If this lasts more than a few minutes, stop and report it. |
movement_authorization_in_progress |
The first send of this payment is still being authorized. | Wait, then send the same request again with the same key. |
wallet_send_intent_not_executing (409) |
The payment was already prepared. | Run catena intents get <id>. Don't use a new key. |
wallet_send_action_not_yet_enabled |
Payments on that network aren't available yet. | Let the user know. Don't retry. |
onchain_network_closed (409) |
Catena has made the network temporarily unavailable. Nothing moved, and payments already in progress will complete. | Don't retry on that network. Use one of the networks in details.alternatives, or let the user know. |
rate_limited (429) |
Your organization sent too many bank payments in a minute. | Wait for Retry-After, then send again. |
intent_not_cancellable (409) |
The intent has already started executing. | Follow it with intents get. |
| 409 on an idempotency key | The same key was reused with different inputs. | Use a new key for a new operation. |
NoteRetrying with the same key
Several of these errors ask your agent to send the same request again with the same idempotency key. The same key with the same inputs will return the original intent, and no money will move a second time. The exception is
movement_wallet_approval_openwithdetails.intentCancelled: true: we cancelled that intent, and its key would only return it, so your agent should send again with a new key. If your agent is starting a new operation, it should use a new key, since a key reused with different inputs will fail with a 409. See Retry safely for the full rules.
Payment reasons
The following codes appear in an intent's reasons field. They are
not returned as errors.
| Reason | Meaning |
|---|---|
agent_signer_not_registered, operator_signature_required |
The agent has no wallet signing key, so the payment will wait for an admin. Once signing setup is done, relink the agent with --relink. |
Report a problem
If you run into an unclear message, a missing command, or an operation the CLI cannot express, we would like to hear about it. You can send feedback to the Catena team from the CLI:
catena feedback --help
catena feedback "What I was trying to do, what happened, and the evidence."