Error catalog (@gala-chain/gala-core-sdk)
Every error the core SDK throws is a GalaSDKError with a stable code, flat params an app
localizes, and a phase (pre_send: nothing was transmitted; in_flight: the request may have
left; post_send: an answer was read). Branch on code, never on message (English, for logs).
A product SDK's error class extends GalaSDKError and adds its own catalog: gswap-sdk's DEX codes
are documented in its docs/other/error-handling.md. A GSwapSDKError can carry any code of
both catalogs; isGalaError(error) recognises an error from any of them, and
isGalaErrorLike / isWalletUserRejection (@gala-chain/gala-core-sdk/wallet) do so without
instanceof, across copies of the SDK, through the registered brand
Symbol.for('@gala-chain/gala-core-sdk/error').
How a failure is classified for Retry and "maybe queued" (classifyFailure) is a product SDK's
decision (gswap-sdk's failure_classification.ts): the descriptions below say what gswap-sdk's
classifier answers.
{/* error-catalog:start (generated by pnpm run docs:error-catalog) */}
| code | phase | params | English template (seed only) | when thrown |
|---|---|---|---|---|
REQUEST_TIMEOUT | in_flight | url:string, timeoutMs:number | Request to {url} timed out after {timeoutMs} ms. | A read or write request exceeded its timeout. A write that times out becomes SUBMISSION_OUTCOME_UNKNOWN (gswap-sdk) or GATEWAY_WRITE_OUTCOME_UNKNOWN (core GatewayWrites). |
TRANSPORT_ERROR | in_flight | url:string | The request to {url} failed before the server answered. | A READ failed before any answer: the default fetch requestor (offline, DNS, CORS), or httpRequestorFromAxios (an answer that is not a response, any rejection with rejectOnHttpError: false, an axios error without a response with true). The original error is cause. A requestor the app supplies is NOT wrapped (its rejection reaches you as it is), and neither is a caller abort. On a write POST the same failure is SUBMISSION_OUTCOME_UNKNOWN (gswap-sdk) or GATEWAY_WRITE_OUTCOME_UNKNOWN (core GatewayWrites). |
INVALID_TIMEOUT | pre_send | field:string, value:number | {field} must be a positive number of milliseconds, or Infinity for no timeout (got {value}). | A timeout option is not a positive number or Infinity. |
GALA_WALLET_NOT_AVAILABLE | pre_send | - | Gala wallet is not available. Please ensure the Gala wallet is connected. | window.gala is absent when GalaWalletSigner signs. |
WALLET_UNAVAILABLE | pre_send | - | No wallet is connected. | The ethers EIP-1193 shim has no provider (nothing connected). |
MALFORMED_WALLET_REQUEST | pre_send | method:string | Wallet {method} request is malformed. | The shim got an unreadable eth_signTypedData_v4 / personal_sign request. |
UNSUPPORTED_WALLET_METHOD | pre_send | method:string | Unsupported wallet method {method}. | The shim got a method other than chainId / typed data / personal_sign. |
INVALID_SIGNATURE | pre_send | scheme:string | Wallet returned an invalid {scheme} signature. | A wallet answered with a signature that is not 130 hex digits; params.scheme is native or personal-sign. |
INVALID_CHAIN_ID | pre_send | chainId:string | Wallet returned an invalid chain id ({chainId}). | eth_chainId answered something that is not a positive integer. |
SIGNER_ADDRESS_MISMATCH | pre_send | - | The signing key does not belong to the expected account. | A lazy private-key signer whose key is not the expected account. |
INVALID_PRIVATE_KEY | pre_send | reason:wrong_length|bad_encoding|not_on_curve|no_key_provided | Invalid private key: {reason}. | A key that is empty, the wrong length, mis-encoded or off the curve; params.reason: no_key_provided (the provider returned nothing, for example a locked wallet: not_sent, Retry is safe), wrong_length, bad_encoding, not_on_curve (invalid_input). Never carries key material. |
SIGNING_FAILED | pre_send | method:string, reason:user_rejected|failed | Signing the {method} request failed ({reason}); nothing was sent. | The signer threw something that is not an SDK error before anything was sent: a locked wallet, an unreachable extension, a wallet that declined (params.reason user_rejected, from the wallet's own code 4001 / ACTION_REJECTED, or failed), or a signer that returned no object. params.method is the contract method; the original error is cause, and the wallet's own code (4001, -32603, 'ACTION_REJECTED') is the typed field error.walletCode when it set one. not_sent: Retry is safe. An SDK error the signer throws itself keeps its own code. |
KEY_PROVIDER_FAILED | pre_send | - | The signing key could not be fetched; nothing was sent. | The createLazyPrivateKeySigner key provider threw or rejected (the wallet's session slot is locked or unreadable). The original error is cause. not_sent: Retry is safe once the wallet is unlocked. |
INVALID_SIGNING_HASH_LENGTH | pre_send | length:number | secp256k1 can only sign a 32-byte hash (got {length}). | signHash got other than 32 bytes. |
INVALID_WALLET_ADDRESS | pre_send | field:string, value:string | Invalid {field}: "{value}" is not an accepted wallet address form. | A wallet address / selectAddress, a write identity or a read owner not in an accepted form; params.field names it. |
INVALID_ETH_USER_REF_PREFIX | pre_send | field:string, value:string, expected:string | Invalid {field}: "{value}" is not a GalaChain user reference. An eth| reference takes the 40 hex digits of the account with no 0x prefix; write it as "{expected}". | An address was written `eth |
INVALID_DECIMAL | pre_send | value:string | Invalid decimal quantity: {value} | canonicalDecimalString got a non-finite quantity. |
PERSONAL_SIGN_NOT_JSON | pre_send | - | Personal-sign DTO is not valid JSON | gala_signChainDto personal-sign data is not valid JSON. |
PERSONAL_SIGN_NOT_OBJECT | pre_send | - | Personal-sign DTO must be a JSON object | The personal-sign data is JSON but not an object. |
PERSONAL_SIGN_BAD_PREFIX | pre_send | - | Personal-sign DTO prefix is not an EIP-191 "Ethereum Signed Message" header | The personal-sign prefix is not an EIP-191 "Ethereum Signed Message" header. |
PERSONAL_SIGN_ENVELOPE_FIELDS | pre_send | fields:string | Personal-sign DTO carries signing-envelope field(s): {fields} | The personal-sign data carries signing-envelope fields; params.fields lists them. |
PERSONAL_SIGN_NOT_CANONICAL | pre_send | - | Personal-sign DTO is not in canonical serialized form | The personal-sign data is not in canonical serialized form. |
EIP712_NAME_COLLISION | pre_send | name:string | Name collisions are not supported when deriving EIP-712 types ({name}). | Deriving EIP-712 types met two nested structs with one name. |
EIP712_UNSUPPORTED_VALUE | pre_send | valueType:string | Unsupported EIP-712 value of type {valueType}. | Deriving EIP-712 types met a value that has no EIP-712 type. |
TYPED_DATA_NOT_STRING | pre_send | what:string | Invalid typed data: {what} must be a string | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_UNPAIRED_SURROGATE | pre_send | what:string | Invalid typed data: {what} has an unpaired surrogate | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_NOT_HEX_BYTES | pre_send | what:string | Invalid typed data: {what} must be an even-length 0x hex string | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_NOT_SAFE_INTEGER | pre_send | what:string | Invalid typed data: {what} must be a safe integer | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_NOT_INTEGER | pre_send | what:string | Invalid typed data: {what} must be an integer | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_NOT_BOOLEAN | pre_send | - | Invalid typed data: bool must be a boolean | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_BAD_ADDRESS | pre_send | - | Invalid typed data: address must be 0x followed by 40 hex digits | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_BAD_CHECKSUM | pre_send | - | Invalid typed data: address has a bad checksum | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_BYTES_LENGTH | pre_send | type:string, width:number | Invalid typed data: {type} must be exactly {width} bytes | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_OUT_OF_BOUNDS | pre_send | type:string | Invalid typed data: value out of bounds for {type} | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_UNSUPPORTED_TYPE | pre_send | type:string | Invalid typed data: unsupported type "{type}" | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_FIELDS_NOT_LIST | pre_send | typeName:string | Invalid typed data: type {typeName} must be a list of fields | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_FIELD_MALFORMED | pre_send | typeName:string | Invalid typed data: type {typeName} has a field without a string name and type | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_INVALID_FIELD_NAME | pre_send | name:string | Invalid typed data: invalid field name "{name}" | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_DUPLICATE_FIELD | pre_send | name:string, typeName:string | Invalid typed data: duplicate field "{name}" in {typeName} | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_INVALID_TYPE_NAME | pre_send | name:string | Invalid typed data: invalid type name "{name}" | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_CIRCULAR_TYPE | pre_send | typeName:string | Invalid typed data: circular type reference in {typeName} | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_UNKNOWN_FIELD_TYPE | pre_send | type:string, typeName:string | Invalid typed data: unknown type "{type}" in {typeName} | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_NO_PRIMARY_TYPE | pre_send | - | Invalid typed data: missing primary type | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_AMBIGUOUS_PRIMARY_TYPE | pre_send | roots:string | Invalid typed data: ambiguous primary types or unused types ({roots}) | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_ARRAY_EXPECTED | pre_send | type:string | Invalid typed data: {type} array value must be an array | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_ARRAY_LENGTH_MISMATCH | pre_send | - | Invalid typed data: array length mismatch | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_STRUCT_NOT_OBJECT | pre_send | typeName:string | Invalid typed data: {typeName} value must be an object | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_MISSING_FIELD | pre_send | typeName:string, field:string | Invalid typed data: {typeName} value is missing field "{field}" | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_DOMAIN_NOT_OBJECT | pre_send | - | Invalid typed data: domain must be an object | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
TYPED_DATA_INVALID_DOMAIN_KEY | pre_send | key:string | Invalid typed data: invalid typed-data domain key {key} | A dApp eth_signTypedData_v4 payload the encoder refuses (it fails closed rather than coerce). |
INVALID_UNIQUE_KEY | pre_send | uniqueKey:string | The uniqueKey "{uniqueKey}" must be 1-128 characters of A-Z, a-z, 0-9, ".", "_", ":" or "-". | A uniqueKey outside 1-128 chars of A-Za-z0-9._:- (also when confirming). |
INVALID_UNIQUE_KEY_PREFIX | pre_send | uniqueKeyPrefix:string, maxLength:number | uniqueKeyPrefix "{uniqueKeyPrefix}" must be at most {maxLength} characters of A-Z, a-z, 0-9, ".", "_", ":" or "-". | A uniqueKeyPrefix that would make the key invalid. |
CSPRNG_UNAVAILABLE | pre_send | - | No cryptographically secure random source (globalThis.crypto.getRandomValues) is available to mint a uniqueKey or a new wallet; install a getRandomValues polyfill (react-native-get-random-values on Hermes). | A uniqueKey, or a new random wallet (createWallet()), was to be minted on a platform with no crypto.getRandomValues (React Native/Hermes without react-native-get-random-values). Nothing was sent; install the polyfill. The SDK never falls back to Math.random or crypto.randomUUID (Hermes has none). |
INVALID_WRITES_OPTION | pre_send | option:signer|gatewayBaseUrl|httpRequestor|tokenNameResolver | GatewayWrites option {option} is missing or is not of the expected type. | new GatewayWrites(...) without a signer (an object with signObject) or a string gatewayBaseUrl, or with a requestor that is not a function or a resolver without resolveTokenClassKey; params.option names it. |
INVALID_QUANTITY | pre_send | field:string, value:string | {field} must be a positive decimal number of whole tokens, written as a string (got "{value}"). | A write quantity that is not a plain decimal string greater than zero (no sign, exponent, hex or spaces; a JS number is refused). Quantities are whole tokens, signed as written. |
INVALID_TOKEN_REFERENCE | pre_send | field:string, reason:missing|ambiguous|bad_class_key|bad_instance | Invalid token reference {field}: {reason}. | A write or read names its token badly; params.reason: missing, ambiguous (class key and name, or a name with an instance), bad_class_key (a pipe key needs exactly four parts; a bare symbol is never a key; a read filter part must be a non-empty string), bad_instance. params.field is token, tokens[i].token, tokenClassKey, tokenClassKeys[i] or the filter part. |
INVALID_TOKEN_BATCH | pre_send | method:string, count:number, max:number | {method} takes 1 to {max} tokens (got {count}). | A burn (1-50), lock or unlock (1-100), or a token-class read (1-1000 keys), with no tokens or too many. |
INVALID_LOCK_EXPIRES | pre_send | value:string | expires must be a non-negative whole number of epoch milliseconds, 0 for none (got {value}). | A lock expires that is not a non-negative whole number of epoch milliseconds (0 means it never expires and is kept). |
INVALID_LOCK_NAME | pre_send | valueType:string | The lock name must be a string (got a {valueType}). | A lock / unlock name that is not a string. |
NO_TOKEN_NAME_RESOLVER | pre_send | tokenName:string | The token name "{tokenName}" cannot be resolved: no tokenNameResolver is configured. Pass its tokenClassKey instead. | A write names a token by tokenName but GatewayWrites has no tokenNameResolver. |
TOKEN_NAME_RESOLUTION_FAILED | pre_send | tokenName:string | The token name "{tokenName}" could not be resolved to a token class key; nothing was sent. | The app's tokenNameResolver rejected (the original error is cause; an SDK error it throws passes through instead) or answered something that is not a key. Nothing was sent. |
GATEWAY_WRITE_OUTCOME_UNKNOWN | in_flight | method:string, reason:timeout|transport | The outcome of {method} is unknown ({reason}): the request may have reached the gateway. Check the write by its uniqueKey before sending it again. | A gateway write's POST timed out (params.reason timeout) or failed before an answer was read, including a body that broke off (transport). The original error is cause. The write MAY have been applied: keep error.uniqueKey and check it; never send it again under a fresh key. |
GATEWAY_HTTP_ERROR | post_send | method:string, status:number, serverMessage:string (not in message) | The gateway answered {method} with HTTP {status}. | The gateway answered with a non-2xx status that carries no numeric top-level Status (a proxy page, a 5xx, the gateway's nested { error: { ErrorKey, Message } } refusal). params.serverMessage is the chain's Message / the answer's message when it had one; a non-JSON body is error.bodyText. After a write it may or may not have been applied: check error.uniqueKey. After a read (error.write === false) nothing changed. |
GATEWAY_WRITE_REJECTED | post_send | method:string, chainStatus:number, errorKey:string, serverMessage:string (not in message) | GalaChain rejected {method} (Status {chainStatus}, error key "{errorKey}"). | GalaChain refused a write: its answer had a numeric Status other than 1, in any HTTP status (checked before an x-transaction-id header is trusted). params.errorKey / params.serverMessage are its ErrorKey / Message. |
GATEWAY_RESPONSE_INVALID | post_send | method:string | The gateway answered {method} with something that is not a GalaChain result; the write may have been applied. | A 2xx answer to a write that proves nothing: not a JSON object, a non-numeric Status, or no Status and no transaction id. The write may have been applied: check error.uniqueKey. |
INVALID_READS_OPTION | pre_send | option:gatewayBaseUrl|httpRequestor | GatewayReads option {option} is missing or is not of the expected type. | new GatewayReads(...) without a string gatewayBaseUrl, or with a requestor that is not a function; params.option names it. |
INVALID_PAGE_REQUEST | pre_send | field:limit|pageSize|maxPages|bookmark, value:string | {field} is not valid for a paginated read (got {value}): a page size or page count is a whole number from 1 to 10000, a bookmark a string. | A paginated read with a limit / pageSize / maxPages that is not a whole number from 1 to 10 000, or a bookmark that is not a string; params.field names it. Nothing was sent. |
GATEWAY_READ_REJECTED | post_send | method:string, chainStatus:number, errorKey:string, serverMessage:string (not in message) | GalaChain refused {method} (Status {chainStatus}, error key "{errorKey}"). | GalaChain refused a read: its answer had a numeric Status other than 1. params.errorKey / params.serverMessage are its ErrorKey / Message. A read (error.write === false): nothing changed, a retry is safe. |
GATEWAY_READ_RESPONSE_INVALID | post_send | method:string | The gateway answered {method} with something that is not a usable GalaChain result. | A read's answer is not a usable GalaChain result: not { Status: 1, Data }, a row that is not GalaChain's (a numeric quantity, a hold without its expiry, a class without its symbol), a balance of another owner than the one asked for, or a page whose bookmark does not move on. The answer is error.body. |
TOKEN_CLASS_NOT_FOUND | post_send | tokenClassKey:string | GalaChain has no token class {tokenClassKey}. | GalaChain has no class for a key a token-class read asked for (its 404 TOKEN_CLASS_NOT_FOUND, or an answer without that key's row); params.tokenClassKey is the $ composite key the chain named ('' when it named none). |
PAGINATION_LIMIT_EXCEEDED | post_send | method:string, maxPages:number | Reading every page of {method} takes more than {maxPages} pages; narrow the filter or raise maxPages. | A fetchAll... read would need more than maxPages pages. Nothing is returned (never a truncated list): narrow the filter or raise maxPages. |
WALLET_NOT_CONNECTED | pre_send | reason:not_connected|disconnected|unauthorized, operation:string | The wallet is not connected ({reason}): connect it before {operation}. | A ./providers wallet provider has no account: connect() was never called or disconnect() was (not_connected), the wallet reported a disconnection (disconnected: EIP-1193 4900/4901, a disconnect event, an accountsChanged with no account), or it refused the account (unauthorized: 4100). params.operation names what was attempted; a disconnect() while connect() waited for the wallet makes that connect fail with it too. |
WALLET_CONNECTION_FAILED | pre_send | reason:no_accounts|user_rejected|failed | Connecting to the wallet failed ({reason}). | connect() failed: the wallet answered with no account (no_accounts), the person declined (user_rejected), or anything else (failed, also a reported account that is not an Ethereum address). The wallet's error is cause. |
INVALID_WALLET_PROVIDER_CONFIG | pre_send | missing:eip1193_provider|private_key_or_eip1193_provider | A wallet provider cannot be built without {missing}. | A wallet provider was built without what it needs: an ExternalWalletProvider / GalaWalletProvider without a provider object, createWalletProvider with neither a key nor a provider. |
PRIVATE_KEY_NOT_ACCESSIBLE | pre_send | - | This wallet provider signs in the wallet and cannot give out a private key; only a PrivateKeyProvider holds one. | getPrivateKey() on a wallet-backed provider: the key never leaves the wallet. |
INVALID_WALLET_INPUT | pre_send | reason:empty|unrecognized_format|unknown_mnemonic_word|mnemonic_checksum | The wallet input was refused ({reason}): give a private key (64 hex digits) or a 12- or 24-word mnemonic. | createWallet(input) with an input that is empty, neither a key nor 12 / 24 words, or a mnemonic with an unknown word or a wrong checksum; params.reason says which, nothing of the input is shown. |
INVALID_BRIDGE_AMOUNT | pre_send | value:string, reason:not_a_number|not_positive|too_many_decimals | The bridge amount "{value}" was refused ({reason}). | A bridge amount that is not a finite number, not above zero, or has more decimals than the token (toBaseUnits never rounds). Nothing was sent. |
UNSUPPORTED_BRIDGE_TOKEN | pre_send | network:string, symbol:string | {symbol} cannot be bridged with {network}. | A token symbol the bridge has no configuration for on that network. |
BRIDGE_NOT_CONFIGURED | pre_send | network:Ethereum|Solana | {network} bridging is not configured: give the bridge a {network} private key (ethereumPrivateKey / solanaPrivateKey). | An Ethereum or Solana bridge operation on a bridge built without that network's private key. |
INVALID_TRANSACTION_HASH | pre_send | network:Ethereum|Solana, value:string | "{value}" is not a {network} transaction hash. | A transaction hash that is not in the network's format (Ethereum: 0x plus 64 hex digits). |
INVALID_BRIDGE_OPTION | pre_send | option:string | The bridge option {option} is missing or out of range. | A bridge option missing or out of range (params.option), refused when the client, service or strategy is built (never as a library error at the first request): a rate limit that is not above zero, a URL that is not http(s), a bridge contract or wallet address that is not an Ethereum address, a program id or mint that is not a Solana public key, a missing signer or lookup. |
BRIDGE_RESPONSE_INVALID | post_send | method:string, missing:string | GalaConnect answered {method} without a usable {missing}; the request may have been accepted. | GalaConnect answered a bridge write without what the next step needs (params.missing: the bridge request id, the transaction hash, or a JSON answer at all). The request may have been accepted: check before sending it again. |
BRIDGE_READ_RESPONSE_INVALID | post_send | method:string | GalaConnect answered {method} with something that is not a usable result. | GalaConnect answered a bridge READ (configurations, fee, status, balances) with something that is not the JSON the call needs. Nothing changed (error.write === false). |
BRIDGE_WRITE_OUTCOME_UNKNOWN | in_flight | method:string | The outcome of {method} is unknown: the request failed in transit and may have reached GalaConnect. Check it before sending it again. | A GalaConnect bridge write (requestBridgeOut, bridgeTokenOut, registerBridgeTransaction) failed in transit, after any retries: the request may have reached GalaConnect. A read that fails this way is TRANSPORT_ERROR (write: false). |
GALACONNECT_HTTP_ERROR | post_send | method:string, status:number, serverMessage:string (not in message) | GalaConnect answered {method} with HTTP {status}. | GalaConnect answered a bridge call with an HTTP status other than 2xx (params.status; the body as error.body, its first 500 characters as params.serverMessage). error.write says whether the call was a write. |
BRIDGE_TOKEN_NOT_FOUND | post_send | symbol:string | GalaConnect has no verified bridge configuration for {symbol}. | GalaConnect's bridge configurations have no VERIFIED entry for the token symbol (a well-known token such as GALA or GUSDC is resolved without asking). Nothing was sent. |
TOKEN_NOT_WRAPPABLE | post_send | tokenId:string, reason:not_listed|no_counterpart|unknown_channel | {tokenId} cannot be wrapped or unwrapped ({reason}). | A wrap or unwrap of a token the wrappable token list does not have (not_listed), whose counterpart it does not have (no_counterpart, params.tokenId the counterpart), or whose channel is not one a wrap moves between (unknown_channel). Nothing was sent. |
INVALID_WRAP_DIRECTION | pre_send | symbol:string, direction:wrap|unwrap | Cannot {direction} {symbol}: it is on the wrong channel for it (use the other direction). | A wrap of a token already on the asset channel, or an unwrap of one that is not on it: the other direction is the one that moves it. Nothing was sent. |
BRIDGE_REQUEST_REJECTED | post_send | method:string, chainStatus:number, errorKey:string, serverMessage:string (not in message) | GalaChain refused {method} (Status {chainStatus}, error key "{errorKey}"). | GalaChain refused a bridge write that GalaConnect relayed (an answer with Status other than 1: params.chainStatus, its ErrorKey, its Message as params.serverMessage). A refused RequestTokenBridgeOut locked nothing; a refused BridgeTokenOut reaches the caller inside BRIDGE_OUT_OUTCOME_UNKNOWN (the request before it was accepted). error.status is the chain's own ErrorCode when the answer has one: a 409 is a uniqueKey already consumed (an earlier attempt may be applied), no code cannot be judged. |
BRIDGE_OUT_OUTCOME_UNKNOWN | in_flight | step:request_id|bridge_token_out|transaction_hash, bridgeRequestId:string (not in message) | GalaConnect accepted the bridge-out request, which may have locked the tokens, then the bridge-out failed at {step}. Check it before bridging again. | A bridge-out failed AFTER GalaConnect accepted its RequestTokenBridgeOut, so the tokens may be locked: the answer had no bridge request id, BridgeTokenOut failed, or its answer had no transaction hash (params.step; the failure as cause). Whatever that failure was, a new bridge-out would lock the tokens again: keep error.uniqueKey and params.bridgeRequestId (empty when the id never came) and finish this one (BridgeTokenOut with the id) or check it. |
BRIDGE_DEPOSIT_OUTCOME_UNKNOWN | in_flight | network:Ethereum|Solana, step:send|confirmation|registration, transactionHash:string (not in message) | The {network} bridge deposit may have been sent, then its {step} failed. Check the deposit before sending another. | A bridge-in deposit (Ethereum or Solana) failed once it was being sent: sending it, confirming it, or registering it with GalaConnect (params.step; the failure as cause). The funds may have left the wallet: check the deposit (params.transactionHash, empty when the send failed before a hash was known) and register it, never send another. Every refusal BEFORE the send is its own pre-send code. |
BRIDGE_CHAIN_READ_FAILED | post_send | network:Ethereum|Solana, call:string | The {network} read {call} failed or answered something unusable; nothing was sent. | A read of the external chain (params.call: a token balance, allowance, name or permit nonce, a token account, the bridge program's mint lookup) failed or answered something unusable (the failure, if any, as cause). Nothing was sent. |
INSUFFICIENT_BRIDGE_BALANCE | pre_send | network:Ethereum|Solana, symbol:string, needed:string, available:string | The {network} balance of {symbol} is {available}; the bridge needs {needed}. | The wallet's balance of the token on the external chain is below the bridge-in amount (params.needed, params.available, as decimals). Nothing was sent. |
BRIDGE_STATUS_TIMEOUT | in_flight | transactionHash:string (not in message), timeoutMs:number, lastStatus:number | The bridge transaction did not reach a final status within {timeoutMs} ms (last status {lastStatus}); it may still complete. | waitForCompletion reached its timeout before the bridge transaction reached a final status (params.lastStatus, a BridgeStatusCode). The transaction may still complete: wait again or read its status. |
WALLET_CONTEXT_MISSING | pre_send | - | The wallet hooks and the wallet context need a WalletProvider above them. | A ./react wallet hook (or the context value outside any provider) was used with no WalletProvider above it. |
{/* error-catalog:end */}
gala sdk error pre send in flight post swap is like wallet user rejection classify failure classification request timeout ms submission outcome unknown gateway write writes transport http requestor from axios reject on invalid not available signer unavailable malformed eth sign typed data v4 personal unsupported method signature chain id address mismatch private key no provided sent wrong length bad encoding curve input signing failed rejected action code provider create lazy hash select ref prefix decimal canonical string json dto object envelope fields eip712 name collision value type unpaired surrogate hex bytes safe integer boolean checksum out of bounds list field duplicate circular primary ambiguous array expected struct missing domain unique max csprng get random values uuid option base url resolve token class quantity reference instance keys batch lock expires resolver resolution server message body text status response reads page size pages read found pagination limit exceeded fetch all connected accounts changed connection config external accessible bridge amount to units configured transaction register galaconnect wrappable listed counterpart channel wrap direction deposit insufficient balance last wait for completion context