Errors
SkillFiles & storageHow to define and check error classes in Ledger Live. Read when adding a new error, creating an errors.ts file, or checking an error's type.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Errors skill
What this skill tells your AI
The instructions your AI receives, as published by ledgerhq/ledger-live in .agents/skills/errors/SKILL.md and read by ahel’s review.
Each package owns its errors in its own src/errors.ts, as plain native classes.
There is no shared errors lib: the former @ledgerhq/errors package has been removed.
Define errors
A package groups its errors in src/errors.ts. Extend Error directly and set a
stable name. The name string is the contract — keep it stable, it is what
survives across process/serialization boundaries.
// message-only
export class FooNotFound extends Error {
override name = "FooNotFound";
}
// with a default message
export class InvalidChallenge extends Error {
override name = "InvalidChallenge";
constructor() {
super("backend returned an invalid challenge");
}
}
// with extra fields
export class HttpError extends Error {
override name = "HttpError";
readonly status: number | undefined;
constructor(message: string, status?: number) {
super(message);
this.status = status;
}
}
Group a family under a per-package base class so callers can catch the whole set:
export class WalletAuthError extends Error {
override name = "WalletAuthError";
}
export class WalletAuthSignatureError extends WalletAuthError {
override name = "WalletAuthSignatureError";
constructor(cause: unknown) {
super("failed to sign challenge", { cause });
}
}
See libs/ledger-auth/src/errors.ts for a full reference.
cause
Use the native second argument: super(message, { cause }). Error cause was
standardized in ES2022 and is supported by modern runtimes; its TypeScript typing
(ErrorOptions) requires lib: es2022.error (i.e. es2022). Coin modules and
some older packages still target es2020 — there, declare and assign manually:
export class BroadcastError extends Error {
override name = "BroadcastError";
cause?: unknown;
constructor(message: string, cause?: unknown) {
super(message);
this.cause = cause;
}
}
Check error type: prefer error.name
Prefer error.name === "FooNotFound" over instanceof FooNotFound.
instanceof breaks once an error crosses a boundary — desktop/mobile IPC, worker
messaging, or the external @ledgerhq/coin-module-framework — because the object
is rebuilt and loses its prototype. The name string always survives.
// ✅ survives serialization
if (error instanceof Error && error.name === "FooNotFound") { … }
// ⚠️ only works in-process, before any serialization
if (error instanceof FooNotFound) { … }
Use instanceof only when you are certain the error has not crossed a boundary
(e.g. caught in the same module that threw it) and you need the typed fields.
Where errors live
- Logic in one package → that package's
src/errors.ts. - Used only by an app → the app's
src/errors.ts(apps/ledger-live-desktop,apps/ledger-live-mobile). - Shared by several coin modules →
libs/ledger-wallet-framework/src/errors.ts(@ledgerhq/ledger-wallet-framework/errors), the shared home below the coin layer.
Signals
- GitHub stars
- 618
- Forks
- 490
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
errors-ledgerhq- Source
- github.com/ledgerhq/ledger-live