Errors & Codes
WativeError and the WativeErrorCode union — the single typed error the library throws — with the meaning of codes such as PARAMETER_ERROR, INVALID_PRIVATE_KEY, RECORD_LOCKED, WORKSPACE_LOCKED, STORAGE_NOT_DURABLE and UNSUPPORTED_OP.
The library throws exactly one error class: WativeError. Every failure it raises — a bad argument, a locked workspace, a rejected broadcast, an out-of-range key — arrives as a WativeError carrying a machine-readable code from the WativeErrorCode union. You branch on code, not on message text, which is written for humans and may change.
The WativeError shape
WativeError extends the built-in Error, so it has the usual message, name, and stack, plus three typed fields:
class WativeError extends Error {
readonly code: WativeErrorCode;
readonly cause?: unknown;
readonly details?: Record<string, unknown>;
constructor(code: WativeErrorCode, message: string, opts?: WativeErrorOpts);
}
interface WativeErrorOpts {
readonly cause?: unknown;
readonly details?: Record<string, unknown>;
}| Field | Type | Meaning |
|---|---|---|
name | string | Always "WativeError". |
code | WativeErrorCode | The stable, machine-readable code. Branch on this. |
message | string | A human-readable description. Not part of the contract. |
cause | unknown | The underlying error, when one exists (e.g. a wrapped RPC or filesystem error). |
details | Record<string, unknown> | Structured extra context — for example WEAK_PASSWORD carries details.result, the full password check result. |
WativeError and the types WativeErrorCode and WativeErrorOpts are exported from wative-core.
Catching by code
Check instanceof WativeError, then switch on err.code. Because code is a typed union, a switch gives you exhaustiveness help from the compiler.
import { WativeError, type WativeErrorCode } from "wative-core";
try {
// account: an unlocked Account from the workspace
await account.importPrivateKey(pk, "evm");
} catch (err) {
if (err instanceof WativeError) {
switch (err.code) {
case "INVALID_PRIVATE_KEY":
// the key was malformed or out of range — ask the user to re-enter it
break;
case "WORKSPACE_LOCKED":
await ws.unlock(password);
break;
default:
console.error(`${err.code}: ${err.message}`, err.cause);
}
} else {
throw err; // not from wative-core — rethrow
}
}Match on err.code, never on err.message. Messages are descriptive and can change between versions; codes are the stable API.
Code reference
WativeErrorCode is the union of every code the library can throw. The codes are grouped below by area for readability.
Workspace, account & records
| Code | Meaning |
|---|---|
WORKSPACE_LOCKED | An operation needs an unlocked workspace, but it is locked. Reading ws.logger, or any password-backed action after lock(), raises this. |
ACCOUNT_LOCKED | The account or address holding the key is locked. Unlock it before signing or deriving. |
RECORD_LOCKED | An encrypted record cannot be read or saved while it is locked. |
RECORD_NOT_FOUND | A requested record — a network, asset, or stored id — does not exist. |
Passwords & cryptography
| Code | Meaning |
|---|---|
BAD_PASSWORD | The supplied password did not decrypt the record or workspace. |
WEAK_PASSWORD | A password failed the password policy. details.result carries the full PasswordCheckResult. See Password Policy. |
DECRYPT_FAILED | A record's ciphertext could not be decrypted — corrupt, missing, or not valid once unlocked. |
ENCRYPT_FAILED | Encryption failed, for example an invalid key length or a cipher that would not initialize. |
ALGORITHM_IRREVERSIBLE | An inverse operation was requested on a one-way primitive (a KDF such as Argon2 cannot decrypt). |
Keys & mnemonics
| Code | Meaning |
|---|---|
INVALID_PRIVATE_KEY | A private key is not well-formed for its curve — e.g. not a 32-byte hex string, or a scalar at or beyond the secp256k1 group order. |
INVALID_MNEMONIC | A mnemonic is malformed or contains words outside the BIP-39 English wordlist. |
Arguments & storage
| Code | Meaning |
|---|---|
PARAMETER_ERROR | An argument was missing, malformed, or out of range. The most common validation code. |
PROVIDER_IO | A storage backend read or write failed, or a provider-level I/O precondition was violated. |
PERMISSION_DENIED | Storage refused access — a read-only filesystem, or storage that is unavailable. |
DISK_FULL | A write failed because the disk is full or a storage quota was exceeded. |
STORAGE_NOT_DURABLE | The browser refused persistent storage, so a newly created workspace could be evicted and its keys lost. Prompt the user for persistence, or pass { acknowledgeEvictionRisk: true } for a disposable workspace. |
Networks & RPC
| Code | Meaning |
|---|---|
UNSUPPORTED_NETWORK | No network is known for the given chainId or slug. |
RPC_UNREACHABLE | The RPC endpoint could not be reached, or its reply was lost — the outcome is unknown. |
RPC_REJECTED | The endpoint was reached and refused: it answered with a JSON-RPC error object. |
RPC_UNREACHABLE and RPC_REJECTED are deliberately distinct, and the difference is load-bearing for a broadcast. A rejection never reached the chain; an unreachable reply was lost and the request may already have been relayed. Do not collapse the two when deciding whether to retry a send.
Transactions
| Code | Meaning |
|---|---|
TX_BUILD_FAILED | Building, encoding, or decoding a transaction failed. |
TX_SIGN_FAILED | Signing a transaction failed. |
TX_SUBMIT_FAILED | Broadcasting a transaction failed. |
TX_TIMEOUT | A transaction did not reach the awaited state within its timeout. |
TX_DROPPED | A submitted transaction was dropped and never included (surfaced with the dropped transaction status). |
TX_ABORTED | Transaction observation was aborted by the caller. |
General
| Code | Meaning |
|---|---|
UNSUPPORTED_OP | The operation is not supported in this build or on this platform — an unimplemented feature, or a native binding that could not be resolved here. |