Handle Errors
Handle WDK CLI exit statuses, JSON output, stderr, and error codes
Use a command's exit status as the primary success signal. When you request --json, parse stdout separately from stderr and allow for commands that still produce text.
This page describes @tetherto/wdk-cli@1.0.0-beta.7.
Handled Error Envelope
Errors that reach the WDK CLI command handler use this JSON shape:
{
"error": "Wallet 'dev' is not unlocked.",
"code": "WALLET_NOT_UNLOCKED",
"suggestion": "Run: wdk wallet unlock --name dev"
}| Field | Present | Description |
|---|---|---|
error | Always | Human-readable message |
code | Always | Machine-readable code |
suggestion | Sometimes | Recovery guidance |
stack | Only with --verbose when available | JavaScript stack trace |
--verbose adds error stacks. It does not enable general debug logging.
Exit Statuses
| Status | Meaning in beta.7 |
|---|---|
0 | Command, help, or version output completed |
1 | A handled CLI/runtime error or a command-line parsing error occurred |
2 | An unexpected non-Error value or an error outside the normal command handler reached the top level |
Do not treat the presence of stdout as success. Some handled failures emit a JSON object to stdout and exit with status 1.
JSON Output Contract
For most successful commands, --json emits one JSON value followed by a newline on stdout. Handled WDK CLI errors also emit one JSON object on stdout.
The current exceptions are:
| Case | Stdout | Stderr | Status |
|---|---|---|---|
Most successful commands with --json | JSON | Usually empty | 0 |
Handled command error with --json | JSON error envelope | Usually empty | 1, or 2 for a non-Error value |
Argument-parsing error with --json | JSON INVALID_ARGUMENT envelope | Empty | 1 |
Argument-parsing error without --json | Empty | Human-readable Commander error and help | 1 |
Help or version, even with --json | Human-readable text | Empty | 0 |
Successful wdk mcp setup, remove, verify-setup, or list with --json | Human-readable text | Empty | 0 |
Wallet command that opens an interactive prompt with --json | Prompt text and terminal-control bytes, followed by JSON if the command completes | Normal notices or errors can still appear | Depends on result |
wdk send --json | JSON on completion or a handled error | Empty unless another feature writes a notice | Depends on result |
A command using non-empty WDK_PASSPHRASE | Normal command output | Includes a passphrase-source notice | Depends on result |
Do not combine stdout and stderr before parsing JSON. Spinner output and notices can make a combined stream invalid JSON.
--json changes output formatting; it does not make every command non-interactive or guarantee JSON-only stdout when a prompt opens. Wallet create, import, export, unlock, delete, default, rename, and change-passphrase flows can still request secret input. Set a non-empty WDK_PASSPHRASE only when you accept the environment-variable exposure described in Configuration. For a non-interactive import, combine wallet import --seed-stdin --json with WDK_PASSPHRASE; for passphrase rotation, --new-passphrase-stdin reads only the new value and WDK_PASSPHRASE supplies the current one.
Handle Output in a Shell Script
Capture the streams separately and inspect the exit status before parsing. This example requires jq:
#!/usr/bin/env bash
set -euo pipefail
stdout_file=$(mktemp)
stderr_file=$(mktemp)
trap 'rm -f "$stdout_file" "$stderr_file"' EXIT
if wdk get balance \
--network ethereum \
--wallet dev \
--json >"$stdout_file" 2>"$stderr_file"; then
jq . "$stdout_file"
elif jq -e 'type == "object" and has("code")' "$stdout_file" >/dev/null 2>&1; then
jq . "$stdout_file" >&2
exit 1
else
cat "$stderr_file" >&2
exit 1
fiThis pattern handles JSON command and argument errors while retaining a text fallback for output that is not part of the JSON contract.
Error Codes
The following names are defined by beta.7. A code can appear only on commands that reach the corresponding behavior.
| Area | Codes |
|---|---|
| Wallet and key state | KEY_NOT_FOUND, INVALID_SEED_PHRASE, WRONG_PASSPHRASE, WALLET_NOT_UNLOCKED, WALLET_EXISTS, WALLET_LOCKED, PASSPHRASE_MISMATCH |
| Arguments and configuration | INVALID_ARGUMENT, INVALID_INDEX, INVALID_CONFIG, MISSING_CONFIG, INVALID_AMOUNT, INVALID_ADDRESS, INVALID_TOKEN |
| Networks and tokens | NETWORK_NOT_SUPPORTED, TOKEN_NOT_SUPPORTED, NETWORK_ERROR |
| Transactions and providers | INSUFFICIENT_BALANCE, TRANSACTION_FAILED, UNSUPPORTED_MODULE, ENVIRONMENT_MISMATCH, SIGN_FAILED, PROVIDER_UNAVAILABLE, QUOTE_REJECTED |
| Fallbacks | UNKNOWN_ERROR, UNEXPECTED_ERROR |
The code set is not a closed protocol enum. The daemon and WDK dependencies can pass through additional codes. Beta.7 also recognizes and formats several dependency codes, including INSUFFICIENT_FUNDS, SERVER_ERROR, and TIMEOUT. Consumers should preserve unknown code strings instead of rejecting the response.
Common Recovery Paths
The table below describes beta.7. Use the Indexer provider configuration when upgrading an existing Indexer setup.
| Code or symptom | Check |
|---|---|
WALLET_NOT_UNLOCKED | Run wdk wallet unlock --name NAME; confirm that its TTL has not expired |
KEY_NOT_FOUND | Run wdk wallet list; verify the wallet name or default wallet |
WRONG_PASSPHRASE | Retry through the hidden prompt; do not print or log the passphrase |
NETWORK_NOT_SUPPORTED | Run wdk network list; check spelling and custom-network state |
TOKEN_NOT_SUPPORTED | Run wdk token list --network NETWORK; use the registered ticker |
INVALID_ADDRESS | Confirm the recipient format and selected mainnet or testnet; beta.7 rejects recognized mismatches after the unlock check but before fee estimation or broadcast |
MISSING_CONFIG for history | Enable one Indexer provider and configure providers.wdk-indexer.config.apiKey; standalone indexer.* and environment overrides are no longer read |
MISSING_CONFIG for buy or sell | Enable an installed fiat provider and configure providers.NAME.config |
INVALID_ARGUMENT naming several fiat providers | Supply --provider NAME, or the MCP provider field, after inspecting wdk provider list |
INVALID_CONFIG for buy or sell | Check the selected provider's credentials; the error includes its reason |
SIGN_FAILED | Check the application-owned callback endpoint, its response and availability |
QUOTE_REJECTED | Inspect every protocol failure. For a Velora ERC-20 route, follow the allowance prerequisite; do not guess the spender or approval amount. Then correct configuration or try a supported pair or amount |
| Built-in protocol package reported missing | Reinstall @tetherto/wdk-cli@1.0.0-beta.7; wdk module add rejects the current configured built-in version, even if its package is missing |
Custom module reported not installed or version mismatch | Run wdk module add --name PACKAGE to repair its stored custom pin after reviewing the exact package |
| Network or provider disabled by its module | Re-enable the parent with wdk module enable --name PACKAGE, then unlock again |
NETWORK_ERROR, TIMEOUT, or SERVER_ERROR | Check the RPC/indexer endpoint and retry only when repeating the operation is safe |
| Text error with empty stdout | Without --json, treat it as an argument/help parsing failure and inspect stderr |
Partial Results
Some successful aggregate operations omit failed items:
wdk get address --allskips networks that fail address derivation.wdk get balance --allskips networks that fail address or balance lookup.wdk get historywithout--tokenignores failed token batch items and returns successful transfers.wdk swapandwdk bridgereturn successful route previews or executions with unsuccessful protocol quotes listed underskipped.
These commands can exit 0 with an incomplete aggregate or route result. If completeness matters, query each required network or token separately and inspect every skipped protocol before acting. A successful beta.7 cross-network swap preview is not proof that its selected provider received the destination network; do not execute that route shape.