Error Handling
25 typed error codes, retry logic, and error recovery patterns
StarkfiError
All errors in StarkFi use the custom StarkfiError class. Every error carries a typed ErrorCode, a human-readable message, and optional structured details:
class StarkfiError extends Error {
constructor(
public readonly code: ErrorCode,
message: string,
public readonly details?: unknown,
options?: { cause?: unknown }
) {
super(message, options);
this.name = "StarkfiError";
}
toJSON() {
return {
error: true,
code: this.code,
message: this.message,
...(this.details ? { details: this.details } : {}),
};
}
}The toJSON() method ensures errors are consistently serialized in MCP responses and --json CLI output.
Error Codes
StarkFi defines 25 typed error codes organized by domain:
Authentication & Session
| Code | When | Resolution |
|---|---|---|
AUTH_REQUIRED | No active session | Run starkfi auth login |
AUTH_FAILED | Login or verify failed | Check email/OTP and retry |
SESSION_EXPIRED | JWT token expired | Re-authenticate with auth login |
Wallet
| Code | When | Resolution |
|---|---|---|
WALLET_NOT_DEPLOYED | Account contract not deployed | Run starkfi deploy |
WALLET_NOT_FOUND | No wallet associated with session | Re-authenticate |
INSUFFICIENT_BALANCE | Not enough tokens for operation | Check balance and reduce amount |
Transactions
| Code | When | Resolution |
|---|---|---|
TX_FAILED | Transaction execution reverted | Check parameters and try again |
TX_NOT_FOUND | Invalid or unknown transaction hash | Verify the hash is correct |
SIMULATION_FAILED | Dry-run preflight check failed | Review transaction parameters |
Trading
| Code | When | Resolution |
|---|---|---|
SWAP_FAILED | Swap execution error | Check token pair and liquidity |
NO_ROUTE_FOUND | No swap route available via Fibrous | Try a different pair or smaller amount |
SLIPPAGE_EXCEEDED | Price moved beyond tolerance | Increase --slippage or retry |
Staking
| Code | When | Resolution |
|---|---|---|
STAKING_FAILED | Staking operation error | Check amount and pool availability |
VALIDATOR_NOT_FOUND | Unknown validator name | Run starkfi validators to see available options |
EXIT_NOT_READY | Unstake cooldown not passed | Wait for cooldown, check with stake-status |
Lending
| Code | When | Resolution |
|---|---|---|
LENDING_FAILED | Lending operation error | Check balance, allowance, and health factor |
POOL_NOT_FOUND | Invalid pool name or address | Run starkfi lend-pools to see available pools |
Infrastructure
| Code | When | Resolution |
|---|---|---|
PAYMASTER_ERROR | Gas abstraction failed | Check Paymaster credits or gas token balance |
NETWORK_ERROR | RPC or API connectivity issue | Check connection, retry automatically |
RATE_LIMITED | Too many requests to RPC/API | Wait and retry, or configure a custom RPC |
BATCH_LIMIT_EXCEEDED | More than 3 operations in multi-swap | Split into multiple transactions |
Validation
| Code | When | Resolution |
|---|---|---|
INVALID_CONFIG | Bad configuration value | Check starkfi config list |
INVALID_ADDRESS | Malformed Starknet address | Ensure address starts with 0x and is valid |
INVALID_AMOUNT | Non-positive or non-numeric amount | Use a positive number (e.g., 0.1, 100) |
General
| Code | When | Resolution |
|---|---|---|
UNKNOWN | Unexpected error (catch-all) | Check the error message for details |
Starknet Error Parsing
Raw Starknet JSON-RPC errors often contain hex-encoded Cairo short strings (e.g., 0x753235365f737562204f766572666c6f77 → u256_sub Overflow) that are unreadable. The parseStarknetError() utility automatically:
- Decodes hex-encoded short strings from
execution_errorpayloads - Matches known Cairo error patterns against a map of 15 common errors
- Returns a user-friendly message, or passes through the original if no match is found
- Strips
ENTRYPOINT_FAILEDnoise from error chains
Error Map (15 patterns)
| Cairo Error | User-Friendly Message |
|---|---|
u256_sub Overflow | Insufficient balance — you don't have enough tokens (including gas fees) |
u256_add Overflow | Amount overflow — the value is too large |
ERC20: transfer amount exceeds balance | Insufficient token balance for this transfer |
ERC20: burn amount exceeds balance | Insufficient token balance to burn |
ERC20: insufficient allowance | Token approval required — not enough allowance for this operation |
argent/multicall-failed | One or more calls in the transaction failed |
argent/invalid-signature | Invalid signature — try re-authenticating with: starkfi auth login |
argent/invalid-timestamp | Transaction expired — please retry |
is_valid_signature | Signature validation failed — try re-authenticating |
assert_not_zero | Operation failed — a required value was zero |
Contract not found | Contract not found — the target contract does not exist on this network |
UNAUTHORIZED | Unauthorized — session may have expired, try: starkfi auth login |
nonce | Transaction nonce error — please retry |
dusty-collateral-balance | Collateral amount is below the pool's minimum (dust limit). Please increase the amount. |
dusty-debt-balance | Borrow amount is below the pool's minimum (dust limit). Please increase the amount. |
Integration
- CLI:
formatError()inlib/format.tscallsparseStarknetError()before displaying - MCP:
withErrorHandling()inmcp/tools/error-handling.tscallsparseStarknetError()before returning JSON
This ensures both human users and AI agents receive the same readable error messages.
Retry Logic
Network requests use automatic retry with exponential backoff via withRetry():
| Setting | Value |
|---|---|
| Max retries | 2 (3 total attempts) |
| Base delay | 500ms |
| Backoff formula | baseDelay × 2^attempt |
| Retry sequence | 500ms → 1000ms |
Only retryable error codes (specified per call via retryOnCodes) trigger retries. Domain errors like INSUFFICIENT_BALANCE or NO_ROUTE_FOUND fail immediately — there's no point retrying when the input is invalid.
Fetch Timeout
All HTTP requests use fetchWithTimeout() which wraps the native fetch() with an AbortController that auto-cancels after 15 seconds by default. This prevents hanging requests from blocking the CLI or MCP server.
Error Handling Patterns
CLI Commands
CLI commands catch errors at the top level, stop the spinner, and print a formatted error message:
try {
// ... operation
spinner.succeed("Done");
} catch (error) {
spinner.fail("Operation failed");
console.error(formatError(error));
process.exit(1);
}MCP Handlers
MCP handlers return errors as structured JSON, allowing AI clients to parse and understand the failure:
{
"error": true,
"code": "INSUFFICIENT_BALANCE",
"message": "Not enough ETH — have 0.01, need 0.1"
}Simulation Before Execution
Transaction commands support --simulate (CLI) or simulation parameters (MCP) to catch errors before they cost gas. Always simulate first when the outcome is uncertain.
Last updated on