Error Codes
Complete reference for error codes returned by the Veridex SDK and Relayer.
SDK Errors
Authentication Errors
| Code | Message | Cause | Solution |
|---|---|---|---|
PASSKEY_NOT_SUPPORTED | WebAuthn is not supported | Browser/device doesn't support passkeys | Use a supported browser (Chrome 67+, Safari 14+) |
USER_CANCELLED | User cancelled the operation | User dismissed biometric prompt | Prompt user to try again |
CREDENTIAL_NOT_FOUND | No stored credential found | User hasn't registered or credential cleared | Call passkey.register() |
INVALID_CREDENTIAL | Credential is invalid | Corrupted or expired credential | Clear and re-register |
SECURITY_ERROR | Security context required | Not running on HTTPS | Use HTTPS or localhost |
Transaction Errors
| Code | Message | Cause | Solution |
|---|---|---|---|
INSUFFICIENT_BALANCE | Insufficient balance | Vault doesn't have enough tokens | Check balance before transfer |
INVALID_RECIPIENT | Invalid recipient address | Malformed address | Validate address format |
INVALID_AMOUNT | Invalid amount | Zero, negative, or malformed amount | Use positive bigint |
INVALID_TOKEN | Token not supported | Unknown token address | Use supported token |
NONCE_MISMATCH | Nonce mismatch | Transaction already processed or out of order | Refresh and retry |
Session Errors
| Code | Message | Cause | Solution |
|---|---|---|---|
SESSION_EXISTS | Session already active | Tried to create while session exists | Revoke existing session first |
SESSION_EXPIRED | Session has expired | Session exceeded duration | Create new session |
SESSION_LIMIT_EXCEEDED | Session limit exceeded | Transfer exceeds session's maxValue | Create session with higher limit |
SESSION_TOKEN_NOT_ALLOWED | Token not allowed | Token not in session's allowedTokens | Use allowed token or create new session |
SESSION_RECIPIENT_NOT_ALLOWED | Recipient not allowed | Recipient not in allowedRecipients | Use allowed recipient or create new session |
Spending Limit Errors
| Code | Message | Cause | Solution |
|---|---|---|---|
SPENDING_LIMIT_EXCEEDED | Spending limit exceeded | Transfer exceeds configured limit | Wait for reset or adjust limits |
DAILY_LIMIT_EXCEEDED | Daily limit exceeded | 24-hour limit reached | Wait for reset |
PER_TX_LIMIT_EXCEEDED | Per-transaction limit exceeded | Single transfer too large | Split into smaller transfers |
Chain Errors
| Code | Message | Cause | Solution |
|---|---|---|---|
UNSUPPORTED_CHAIN | Chain not supported | Chain not in SDK configuration | Use supported chain |
CHAIN_UNAVAILABLE | Chain unavailable | RPC not responding | Try again or use different RPC |
RPC_ERROR | RPC request failed | Network or RPC issues | Retry with backoff |
Relayer Errors
Submission Errors
| Code | HTTP | Message | Cause | Solution |
|---|---|---|---|---|
INVALID_SIGNATURE | 400 | Signature verification failed | WebAuthn signature invalid | Ensure correct payload signing |
INVALID_PAYLOAD | 400 | Invalid request payload | Malformed JSON or missing fields | Check request format |
UNSUPPORTED_ACTION | 400 | Action not supported | Unknown action type | Use valid action |
VAULT_NOT_FOUND | 400 | Vault doesn't exist | Vault not deployed on target chain | Create vault first |
Rate Limiting
| Code | HTTP | Message | Cause | Solution |
|---|---|---|---|---|
RATE_LIMITED | 429 | Too many requests | Exceeded rate limit | Wait and retry with exponential backoff |
VAULT_RATE_LIMITED | 429 | Vault rate limited | Too many requests from vault | Wait 60 seconds |
Relay Errors
| Code | HTTP | Message | Cause | Solution |
|---|---|---|---|---|
RELAY_FAILED | 500 | Relay transaction failed | On-chain execution failed | Check error details, may need more gas |
RELAYER_ERROR | 500 | Internal relayer error | Relayer service issue | Retry or contact support |
INSUFFICIENT_RELAYER_BALANCE | 503 | Relayer out of funds | Relayer needs refunding | Use different relayer or wait |
Wormhole Errors
| Code | HTTP | Message | Cause | Solution |
|---|---|---|---|---|
VAA_NOT_FOUND | 404 | VAA not yet available | Guardians haven't attested | Wait and retry (~60s) |
VAA_EXPIRED | 400 | VAA has expired | VAA too old | Re-initiate transaction |
INVALID_VAA | 400 | Invalid VAA | Malformed or tampered VAA | Re-initiate transaction |
WORMHOLE_UNAVAILABLE | 503 | Wormhole service unavailable | Guardian network issues | Wait and retry |
Handling Errors
JavaScript/TypeScript
import { createSDK } from '@veridex/sdk';
const sdk = createSDK('base', { network: 'testnet' });
try {
await sdk.transferViaRelayer({
token: USDC,
recipient: '0x...',
amount: parseUnits('100', 6),
});
} catch (error) {
switch (error.code) {
case 'INSUFFICIENT_BALANCE':
showToast('Not enough tokens in your wallet');
break;
case 'SPENDING_LIMIT_EXCEEDED':
showToast(`Limit exceeded. Available: ${error.available}`);
break;
case 'SESSION_EXPIRED':
// Prompt to create new session
await sdk.sessions.create({ duration: 3600 });
// Retry transfer
break;
case 'RATE_LIMITED':
// Wait and retry
await sleep(error.retryAfter * 1000);
// Retry transfer
break;
case 'RELAYER_UNAVAILABLE':
showToast('Service temporarily unavailable. Please try again.');
break;
default:
console.error('Unexpected error:', error);
showToast('Something went wrong. Please try again.');
}
}React Error Boundary
import { Component, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback: ReactNode;
}
interface State {
hasError: boolean;
error?: Error;
}
class VeridexErrorBoundary extends Component<Props, State> {
state: State = { hasError: false };
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
render() {
if (this.state.hasError) {
const code = (this.state.error as any)?.code;
if (code === 'PASSKEY_NOT_SUPPORTED') {
return <div>Your browser doesn't support passkeys.</div>;
}
return this.props.fallback;
}
return this.props.children;
}
}Agent SDK Errors
The Agent SDK (@veridex/agentic-payments) has its own error class and codes:
import { AgentPaymentError, AgentPaymentErrorCode } from '@veridex/agentic-payments';| Code | Description | Retryable |
|---|---|---|
LIMIT_EXCEEDED | Transaction exceeds daily or per-tx spending limit | No |
INSUFFICIENT_BALANCE | Not enough tokens in session wallet | No |
SESSION_EXPIRED | Session key has expired | No |
CHAIN_NOT_SUPPORTED | Chain ID not in allowedChains | No |
TOKEN_NOT_SUPPORTED | Token not available on target chain | No |
NETWORK_ERROR | Network or RPC failure | Yes |
X402_PAYMENT_FAILED | x402 payment negotiation failed | Yes |
SIGNATURE_FAILED | Transaction signing failed | No |
Handling Agent SDK Errors
try {
await agent.pay({ chain: 10004, token: 'USDC', amount: '100000000', recipient: '0x...' });
} catch (error) {
if (error instanceof AgentPaymentError) {
console.log('Code:', error.code);
console.log('Message:', error.message);
console.log('Retryable:', error.retryable);
console.log('Suggestion:', error.suggestion);
switch (error.code) {
case AgentPaymentErrorCode.LIMIT_EXCEEDED:
console.log('Over budget — wait for daily reset');
break;
case AgentPaymentErrorCode.INSUFFICIENT_BALANCE:
console.log('Need more tokens:', error.suggestion);
break;
case AgentPaymentErrorCode.SESSION_EXPIRED:
console.log('Re-initialize agent wallet');
break;
case AgentPaymentErrorCode.NETWORK_ERROR:
if (error.retryable) {
console.log('Retrying...');
}
break;
}
}
}Stacks-Specific Errors
| Code | Description | Cause |
|---|---|---|
STACKS_SPONSORSHIP_LIMIT | Sponsorship rate limit exceeded | Too many sponsored txs per hour |
STACKS_POST_CONDITION_FAIL | Post-condition validation failed | Transaction would transfer more than allowed |
STACKS_NONCE_ERROR | Nonce mismatch on Stacks | Concurrent transaction submission |
STACKS_CONTRACT_ERROR | Clarity contract execution error | Invalid arguments or state |
Error Response Format
All errors follow this format:
Core SDK
interface VeridexError extends Error {
code: string; // Machine-readable error code
message: string; // Human-readable message
details?: { // Additional context
[key: string]: any;
};
retryAfter?: number; // Seconds to wait (for rate limits)
httpStatus?: number; // HTTP status code (relayer errors)
}Agent SDK
interface AgentPaymentError extends Error {
code: AgentPaymentErrorCode; // Typed error code enum
message: string; // Human-readable message
retryable: boolean; // Whether the operation can be retried
suggestion?: string; // Suggested action for the user/agent
}Example (Core SDK):
{
"code": "SPENDING_LIMIT_EXCEEDED",
"message": "Transfer exceeds daily spending limit",
"details": {
"limitType": "daily",
"limit": "1000000000000000000",
"attempted": "2000000000000000000",
"available": "500000000000000000",
"resetsAt": 1704153600
}
}Example (Agent SDK):
{
"code": "LIMIT_EXCEEDED",
"message": "Transaction of $150.00 exceeds daily limit of $100.00",
"retryable": false,
"suggestion": "Reduce amount to $75.00 or wait for daily reset at 2026-02-15T00:00:00Z"
}