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 */}