XChain Platform SDK: Error Reference

This document covers all error classes thrown by the XChain Platform SDK, their codes, and how to handle them in application code.


Error Hierarchy

All SDK errors extend a common base class:

flowchart TD
    ERR["Error"]
    SDKERR["SDKError"]
    VAL["SDKValidationError"]
    FMT["SDKFormatError"]
    ENC["SDKEncoderError"]
    EXP["SDKExplorerError"]
    HUB["SDKHubError"]
    CFG["SDKConfigError"]
    CONTRACT["SDKContractError"]
    WALLET["SDKWalletError"]
    AUTH["SDKAuthError"]
    MSG["SDKMessagingError"]
    ACTION["SDKActionError"]
    MUSIG["SDKMuSigError"]
    GATED["SDKGatedFileError"]
    POLICY["SDKPolicyError"]
    X402["SDKX402Error"]

    ERR --> SDKERR
    SDKERR --> VAL
    SDKERR --> FMT
    SDKERR --> ENC
    SDKERR --> EXP
    SDKERR --> HUB
    SDKERR --> CFG
    SDKERR --> CONTRACT
    SDKERR --> WALLET
    SDKERR --> AUTH
    SDKERR --> MSG
    SDKERR --> ACTION
    SDKERR --> MUSIG
    SDKERR --> GATED
    SDKERR --> POLICY
    SDKERR --> X402

Every error instance carries four properties:

Property Type Description
name string Class name (e.g. "SDKValidationError")
code string Machine-readable error code (see below)
message string Human-readable description
details object Extra context (field name, rejected value, etc.): may be empty {}

Error Classes

Class When thrown
SDKValidationError Invalid input, missing required fields, bad field values
SDKFormatError No format version can represent the provided fields
SDKEncoderError Encoder RPC or network errors
SDKExplorerError Explorer HTTP or network errors
SDKHubError Hub unreachable
SDKConfigError Missing required configuration (encoder URL, explorer URL, etc.)
SDKContractError Contract-specific errors: code too large, invalid hex, bad contract index, etc.
SDKWalletError Key management, address derivation, PSBT signing, broadcasting, UTXO queries
SDKAuthError Challenge generation, message signing, signature verification errors
SDKMessagingError Message encryption, decryption, and public key lookup errors
SDKActionError Transaction lifecycle failures: confirmation timeout, action rejected by indexer
SDKMuSigError MuSig2 aggregation and signing errors
SDKGatedFileError Token-gated file encryption/decryption errors
SDKPolicyError Agent session policy violations: action denied, cap exceeded, corrupt state
SDKX402Error HTTP 402 payment flow errors: bad invoice, payment not found, etc.

Error Codes Reference

SDKValidationError

Thrown during action validation before any network call is made.

Code Details properties Description
MISSING_ACTION None No action field was provided in the request
UNKNOWN_ACTION None The action name is not a recognized XChain ACTION type
MISSING_REQUIRED_FIELD field A field required for this action was not provided
INVALID_FIELD_VALUE field, value, constraint A field value is out of range or the wrong type
INVALID_TICK_NAME None TICK name violates naming rules (length, characters, reserved names)
INVALID_TICK_ID None A ^ID reference is not a valid numeric index
FORBIDDEN_CHARACTER None A text field contains a `
BATCH_CONSTRAINT count (for MINT/ISSUE violations) A BATCH protocol rule was violated (nested BATCH, FILE action, more than 1 MINT, more than 1 ISSUE)
BATCH_EMPTY None A batch was built with no actions queued
ENCODING_DATA_TOO_LARGE suggestion The serialized action string exceeds 76 bytes (the OP_RETURN user-data limit; 80 bytes total per output including the 4-byte XCHN prefix)
MISSING_COMPRESSED_PUBKEY None A MULTISIGN encoding was requested without providing a compressedPubKey

SDKFormatError

Thrown by the format selector when it cannot choose a format version for the action.

Code Details properties Description
UNKNOWN_ACTION action The action name has no registered formats
NO_MATCHING_FORMAT action, populatedFields, availableFormats None of the available format versions can represent all the provided fields. availableFormats is an object keyed by version, each entry listing the version’s fields and which of the developer’s fields did not fit

SDKEncoderError

Thrown when communication with the xchain-encoder service fails.

Code Description
ENCODER_RPC_ERROR The encoder returned a JSON-RPC error response
ENCODER_HTTP_{status} The encoder returned an unexpected HTTP status code (e.g. ENCODER_HTTP_500)
ENCODER_TIMEOUT The request to the encoder timed out
ENCODER_NETWORK A network-level connection failure (ECONNREFUSED, etc.)
MISSING_DATA createTx was called without providing the action data payload
MISSING_PUBKEY createTx was called without providing the sender’s public key
MISSING_P2SH_HASH spendP2sh was called without the P2SH script hash
MISSING_P2SH_HEX spendP2sh was called without the redeem script hex
MISSING_TX_HEX broadcastTx was called without providing the signed transaction hex
MISSING_ADDRESS getUTXOs was called without providing an address

SDKExplorerError

Thrown when communication with the xchain-explorer service fails.

Code Description
EXPLORER_HTTP_{status} The explorer returned an unexpected HTTP status code (e.g. EXPLORER_HTTP_404)
EXPLORER_TIMEOUT The request to the explorer timed out
EXPLORER_NETWORK A network-level connection failure
INVALID_NETWORK The configured network string is not recognized

SDKHubError

Thrown when the xchain-hub config oracle cannot be reached.

Code Description
HUB_UNAVAILABLE The hub did not respond or returned an error

SDKConfigError

Thrown at call time when a required service URL has not been configured.

Code Description
EXPLORER_NOT_CONFIGURED An explorer operation was attempted but no explorer URL is set
ENCODER_NOT_CONFIGURED An encoder operation was attempted but no encoder URL is set
HUB_NOT_CONFIGURED A hub operation was attempted but no hub URL is set

SDKContractError

Thrown for contract-specific issues during DEPLOY, EXECUTE, DEPOSIT, or WITHDRAW operations.

Code Details properties Description
CODE_TOO_LARGE bytes, limit Contract source exceeds the 64KB size limit
CODE_SYNTAX_ERROR None acorn parse failure during pre-validation
CODE_ENCODING_FAILED None Base64 encoding or decoding failure
INVALID_CONTRACT_INDEX None CONTRACT_ACTION_INDEX is not a positive integer
INVALID_METHOD_NAME None METHOD is empty or contains forbidden characters
INVALID_PARAM_VALUE field, index, value A parameter contains pipe or semicolon characters
CONTRACT_NOT_FOUND None Explorer lookup returned no contract for the given index
CONTRACT_DISABLED None Contract is disabled (for execute/deposit operations)

SDKWalletError

Thrown by wallet operations: key management, address derivation, PSBT signing, transaction broadcasting, and UTXO queries.

Code Description
NETWORK_NOT_CONFIGURED A wallet operation requiring network parameters was called without a network configured
INVALID_WIF WIF string is malformed or cannot be decoded
NETWORK_MISMATCH The WIF key’s network byte does not match the SDK’s configured network
INVALID_PUBLIC_KEY Public key buffer is malformed or has an invalid length
INVALID_ADDRESS_TYPE Unknown address type requested (not p2pkh, p2wpkh, or p2sh-p2wpkh)
SEGWIT_NOT_SUPPORTED A SegWit address type was requested on a Dogecoin network
INVALID_PSBT The hex string could not be parsed as a valid PSBT
SIGN_FAILED PSBT signing failed (wrong key for inputs, etc.)
FINALIZE_FAILED PSBT finalization failed after signing
INVALID_TX_HEX Missing or empty transaction hex for broadcasting
ENCODER_REQUIRED broadcastTx or getUTXOs was called on wallet directly without an encoder client
BROADCAST_FAILED The encoder returned an error when broadcasting the transaction
INVALID_ADDRESS Address is missing or invalid for a UTXO query
UTXO_FETCH_FAILED The encoder returned an error when fetching UTXOs

SDKAuthError

Thrown by authentication operations: challenge generation, message signing, and signature verification setup errors. Note: verifyOwnership and verifyMessage return { valid: false } instead of throwing.

Code Description
NETWORK_NOT_CONFIGURED A signing or verification operation was called without a network configured
INVALID_ADDRESS Address is missing or not a string for challenge generation
INVALID_MESSAGE Message is missing or not a string for signing
INVALID_WIF WIF string is malformed or cannot be decoded
SIGN_FAILED Message signing failed unexpectedly

SDKMessagingError

Thrown by messaging operations: encryption, decryption, public key lookup, and message sending.

Code Details properties Description
NETWORK_NOT_CONFIGURED None A messaging operation requiring network parameters was called without a network configured
INVALID_MESSAGE None Plaintext is missing, not a string, empty, or an invalid type for the chosen encryption method
INVALID_PUBKEY length (when length mismatch) Recipient public key is missing, an invalid length (not 33 or 65 bytes), or not a valid secp256k1 curve point
INVALID_CIPHERTEXT None Ciphertext is missing, too short to contain ECIES overhead, or otherwise malformed
INVALID_WIF None WIF private key is missing, not a string, or cannot be decoded for the configured network
DECRYPTION_FAILED None AES-GCM decryption failed (wrong key, corrupted ciphertext, or bad auth tag)
INVALID_ADDRESS None Address is missing or not a string when looking up a public key or fetching messages
INVALID_COIN None Destination coin is missing or not a recognized chain identifier (BTC, LTC, DOGE)
INVALID_DESTINATION None Destination address is missing or not a string
INVALID_METHOD method Encryption method number is not one of the recognized values (1=ECIES, 2=ECDH, 3=AES, null=plaintext)
INVALID_KEY None AES shared key is missing for aesEncrypt or aesDecrypt
INVALID_TYPE name A value passed as a hex string or Buffer was neither
PUBKEY_NOT_FOUND address ECIES send: the explorer found no public key for the destination address. The address has not yet sent any on-chain transactions
SHARED_SECRET_REQUIRED None ECDH send (method=2): sharedSecret was not provided. Derive it with deriveSharedSecret() first
SHARED_KEY_REQUIRED None AES send (method=3): sharedKey was not provided
ENCODER_REQUIRED None send() was called without providing encoder options
EXPLORER_REQUIRED None getPublicKey() or getMessages() was called without providing an explorer client
SDK_REQUIRED None send() was called directly on MessagingUtils instead of via sdk.sendMessage()

SDKActionError

Thrown by the action waiter (ActionWaiter) when waiting for a broadcast transaction to be indexed.

Code Details properties Description
CONFIRMATION_TIMEOUT txid, timeout The transaction was broadcast but the indexer did not confirm it within the timeout window (default 120 seconds). The transaction may still be processed; callers may retry with a longer timeout
ACTION_REJECTED txid, action, reason The transaction was indexed but one or more of its actions were marked invalid by the indexer. reason contains the indexer status string (e.g. "invalid: insufficient funds (FEE)"). action is the full indexed action object

SDKPolicyError

Thrown by AgentSession.submit() when a declarative spending policy check fails, or during construction when the policy object is invalid. See Agent Wallets.

Code Description
POLICY_INVALID Policy object is malformed at construction time (missing allowedActions, bad window hours, missing confirmation handler)
POLICY_ACTION_DENIED The action type is not in allowedActions
POLICY_DESTINATION_DENIED A destination address is not in allowedDestinations
POLICY_AMOUNT_EXCEEDED A single-action amount exceeds the per-action cap (maxPerAction)
POLICY_WINDOW_AMOUNT_EXCEEDED Adding this amount would breach the rolling-window token cap (maxPerWindow.perTick)
POLICY_WINDOW_COUNT_EXCEEDED The rolling window already holds maxPerWindow.maxActions actions
POLICY_CONFIRMATION_DENIED Amount was above the confirmAbove threshold and the confirmation handler returned false
POLICY_STATE_CORRUPT The usage-state file is unreadable or structurally invalid: blocks all submits; indicates a corrupt state file, not a policy denial and should not be retried. Remove or repair the file deliberately to recover.

SDKX402Error

Thrown by the X402Gateway and X402Client during HTTP 402 payment flows. See src/x402.js.

Code Description
X402_NO_PROOF The X-Payment header is absent
X402_WRONG_COIN Proof coin does not match the gateway’s configured coin
X402_BAD_INVOICE The invoice nonce in the proof is malformed (not a 32-hex-char string)
X402_UNKNOWN_INVOICE No stored invoice matches the nonce
X402_INVOICE_ALREADY_USED Invoice has already been claimed (replay attempt)
X402_INVOICE_EXPIRED Invoice TTL has elapsed including the expiry grace window
X402_PAYMENT_NOT_FOUND No matching on-chain SEND (or mempool row for 0-conf) was found for the proof
X402_INSUFFICIENT_HOLDING Dispenser-scheme: payer does not hold the required minimum balance of holdTick
X402_DEPOSIT_EXHAUSTED Deposit-scheme: payer’s deposited balance is insufficient for one more call
X402_STATE_CORRUPT An invoice file or deposit ledger file is unreadable
X402_NO_USABLE_SCHEME Client-side: the gateway’s challenge contains no xchain-send offer
X402_PRICE_TOO_HIGH Client-side: the gateway’s offered amount exceeds the client’s maxAmount
X402_PAYMENT_NOT_ACCEPTED Client-side: payment was broadcast but the gateway did not accept it after all retries

Catching Errors

Import the error classes you need and use instanceof checks in your catch block. Check error.code for fine-grained handling and error.details for additional context.

const {
    SDKValidationError,
    SDKFormatError,
    SDKEncoderError,
    SDKConfigError,
    SDKContractError,
    SDKWalletError,
    SDKAuthError
} = require('@xchain/sdk/src/errors');

try {
    let result = await sdk.createAction({
        action: 'SEND',
        params: { tick: 'DOGE.TOKEN', amount: 100, destination: 'abc123' }
    });
    console.log(result.actionString);

} catch (err) {

    if (err instanceof SDKValidationError) {
        // Input was rejected before any network call
        console.error('Validation failed:', err.code, err.message);

        if (err.code === 'MISSING_REQUIRED_FIELD') {
            console.error('Missing field:', err.details.field);
        }
        if (err.code === 'INVALID_FIELD_VALUE') {
            console.error('Bad value for', err.details.field, ':', err.details.value);
            console.error('Constraint:', err.details.constraint);
        }
        if (err.code === 'BATCH_CONSTRAINT') {
            console.error('BATCH rule violated:', err.message);
        }

    } else if (err instanceof SDKFormatError) {
        // No format version fits the provided fields
        console.error('Format selection failed:', err.code);

        if (err.code === 'NO_MATCHING_FORMAT') {
            console.error('Provided fields:', err.details.populatedFields);
            console.error('Available formats:', JSON.stringify(err.details.availableFormats, null, 2));
        }

    } else if (err instanceof SDKEncoderError) {
        // Encoder RPC or network problem
        console.error('Encoder error:', err.code, err.message);

    } else if (err instanceof SDKConfigError) {
        // Service URL not configured
        console.error('Configuration error:', err.code);

    } else if (err instanceof SDKContractError) {
        // Contract-specific error (code too large, bad hex, etc.)
        console.error('Contract error:', err.code, err.message);

    } else if (err instanceof SDKWalletError) {
        // Wallet operation failed (key import, PSBT signing, broadcast, etc.)
        console.error('Wallet error:', err.code, err.message);

    } else if (err instanceof SDKAuthError) {
        // Auth operation failed (challenge generation, message signing)
        console.error('Auth error:', err.code, err.message);

    } else if (err instanceof SDKMessagingError) {
        // Messaging operation failed (encryption, decryption, pubkey lookup)
        console.error('Messaging error:', err.code, err.message);

    } else if (err instanceof SDKActionError) {
        // Transaction lifecycle failure (confirmation timeout, action rejected by indexer)
        console.error('Action error:', err.code, err.message);
        if (err.code === 'CONFIRMATION_TIMEOUT') {
            console.error('Transaction was broadcast but not indexed within timeout');
        }
        if (err.code === 'ACTION_REJECTED') {
            console.error('Action was indexed but marked invalid:', err.details.reason);
        }

    } else {
        // Unexpected error; rethrow
        throw err;
    }
}

Validation Dry-Run

Use sdk.validateAction() to check an action’s fields before constructing a transaction. It runs the validation pipeline but does not call the encoder and does not throw. It is useful for pre-flight checks in forms or CLI wizards.

const result = sdk.validateAction('ISSUE', {
    tick: 'MY.TOKEN',
    maxSupply: 21000000,
    decimals: 8
});

if (result.valid) {
    console.log('Action is valid; ready to submit');
} else {
    console.error('Will not encode:', result.errors);
    // result.errors is an array of { code, message, details } objects
}

validateAction(action, params) takes the action name as the first argument and the params object as the second. It always returns { valid, errors } and never throws.


Copyright © 2025–2026 Dankest, LLC

Based on XChain Platform by Dankest, LLC – https://dankest.llc

Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later) with a commercial license available for proprietary use.

You may use, modify, and distribute this material under the terms of the License. See LICENSE and NOTICE for full terms. See the licensing overview.

Edit this page on GitHub ↗