FuelLabs/fuels-ts · error · FuelError
HD_WALLET_ERROR
HD_WALLET_ERROR
Error message
invalid path - ${path} What it means
Thrown by parsePath when a BIP-32 derivation path is malformed: either it has no components after splitting on '/', or it begins with 'm' at a non-zero depth (you cannot re-anchor an already-derived wallet). HDWallet.derivePath uses this to convert a string path into numeric child indices. The path must follow the m/44'/117'/0'/0/0 convention.
Source
Thrown at packages/account/src/hdwallet/hdwallet.ts:45
}
return testnet ? TestnetPRV : MainnetPRV;
}
function isPublicExtendedKey(extendedKey: Uint8Array) {
return [MainnetPUB, TestnetPUB].includes(hexlify(extendedKey.slice(0, 4)));
}
function isValidExtendedKey(extendedKey: Uint8Array) {
return [MainnetPRV, TestnetPRV, MainnetPUB, TestnetPUB].includes(
hexlify(extendedKey.slice(0, 4))
);
}
function parsePath(path: string, depth: number = 0) {
const components = path.split('/');
if (components.length === 0 || (components[0] === 'm' && depth !== 0)) {
throw new FuelError(ErrorCode.HD_WALLET_ERROR, `invalid path - ${path}`);
}
if (components[0] === 'm') {
components.shift();
}
return components.map((p) =>
~p.indexOf(`'`) ? parseInt(p, 10) + HARDENED_INDEX : parseInt(p, 10)
);
}
type HDWalletConfig = {
privateKey?: BytesLike;
publicKey?: BytesLike;
chainCode: BytesLike;
depth?: number;
index?: number;
parentFingerprint?: string;View on GitHub (pinned to b3f37c91ac)
Solutions
- Use absolute paths only on a master (depth 0) HDWallet from fromSeed/fromExtendedKey; on children, use relative paths without the 'm' prefix.
- Validate the path format before calling derivePath: /^m(\/[0-9]+'?)+$/ for a master wallet.
- Keep a reference to the master wallet and derive fresh from it rather than chaining off arbitrary nodes.
Example fix
// before
const child = master.derivePath("m/44'/117'/0'");
child.derivePath("m/0/0"); // 'm' at depth > 0
// after
const child = master.derivePath("m/44'/117'/0'");
child.derivePath("0/0"); // relative path Defensive patterns
Strategy: validation
Validate before calling
// Validate a BIP-32 path before deriving
function isValidPath(path: string, isMaster: boolean): boolean {
if (!path) return false;
const re = isMaster ? /^(m)(\/[0-9]+['\h]?)*$/ : /^([0-9]+['\h]?)(\/[0-9]+['\h]?)*$/;
return re.test(path);
}
if (isValidPath(path, master.depth === 0)) master.derivePath(path); Type guard
function isAbsolutePath(path: string): boolean {
return path.startsWith('m');
} Try / catch
try {
child.derivePath(path);
} catch (e) {
if (e instanceof FuelError && e.code === ErrorCode.HD_WALLET_ERROR && /invalid path/.test(e.message)) {
// strip leading 'm' for child wallets, or re-derive from master
} else throw e;
} Prevention
- Only use 'm'-prefixed absolute paths on the master node (depth 0).
- On derived nodes, use relative paths without 'm'.
- Derive from a cached master rather than chaining off arbitrary nodes.
When it happens
Trigger: Calling hdwallet.derivePath('') (empty), hdwallet.derivePath('m/...') on a wallet whose depth is already > 0 (re-deriving from 'm' on a child), or a path like '//0/0' that splits to empty segments.
Common situations: Reusing an already-derived HDWallet and calling derivePath with an absolute 'm/...' path, passing a user-typed path with stray slashes, or building a path string incorrectly (concatenation bugs).
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/861a0c685804c952.
Report an issue: GitHub.