FuelLabs/fuels-ts · error · FuelError
INSUFFICIENT_FUNDS
INSUFFICIENT_FUNDS
Error message
Insufficient funds to consolidate.
Asset ID: ${baseAssetId}
Owner: ${account.address.toB256()} What it means
Thrown by consolidateCoins() when, after fetching and sorting all base-asset coins for the account, the 'funding' array is empty. With no funding coins, the account cannot pay gas for even the first consolidation transaction. The message echoes the base asset id and owner address for diagnosis.
Source
Thrown at packages/account/src/utils/consolidate-coins.ts:145
let funding: Coin[] = [];
let dust: Coin[] = [];
// We get the largest coin/s for funding purposes
if (isBaseAsset) {
const coins = await getAllCoins(account, baseAssetId).then(sortCoins);
funding = coins.slice(0, numberOfFundingCoins);
dust = coins.slice(numberOfFundingCoins);
} else {
funding = await getAllCoins(account, baseAssetId)
.then(sortCoins)
.then((coins) => coins.slice(0, numberOfFundingCoins));
dust = await getAllCoins(account, assetId).then(({ coins }) => coins);
}
// There a better way of detecting whether the account has enough funds to consolidate
if (funding.length === 0) {
throw new FuelError(
ErrorCode.INSUFFICIENT_FUNDS,
`Insufficient funds to consolidate.\n\tAsset ID: ${baseAssetId}\n\tOwner: ${account.address.toB256()}`
);
}
const batches = [
...splitEvery(batchSize, funding),
// We leave one coin for the funding coin
...splitEvery(batchSize - 1, dust),
];
const txs: ScriptTransactionRequest[] = batches.map((batch) => {
const request = new ScriptTransactionRequest({
scriptData: '0x',
});
// Add our dust coins as inputs
request.addResources(batch);View on GitHub (pinned to b3f37c91ac)
Solutions
- Fund the account with base-asset coins (e.g. via a faucet or transfer) before consolidating.
- Verify account.address matches the account that owns the coins you expect.
- Confirm provider.getBaseAssetId() returns the asset id the account is funded with.
- If consolidating a non-base asset, the account still needs base-asset coins to pay gas.
Example fix
// before
await account.consolidateCoins({ assetId }); // account has no base asset
// after
await faucet.fund(account.address, baseAssetId, 1_000_000);
await account.consolidateCoins({ assetId }); Defensive patterns
Strategy: validation
Validate before calling
const baseCoins = await account.getCoins(baseAssetId);
if (baseCoins.coins.length === 0) {
throw new Error('Account has no base-asset coins; fund it before consolidating.');
} Try / catch
try {
await account.consolidateCoins({ assetId });
} catch (err) {
if (err instanceof FuelError && err.code === ErrorCode.INSUFFICIENT_FUNDS) {
await faucet.fund(account.address, baseAssetId, minBalance);
await account.consolidateCoins({ assetId });
} else throw err;
} Prevention
- Pre-fund accounts with base asset before any consolidation or tx submission.
- Verify provider.getBaseAssetId() matches the asset the account holds.
- Check coin balances via account.getCoins before consolidating.
When it happens
Trigger: Calling account.consolidateCoins / startConsolidation on an account that holds zero coins of the base asset (the fee-paying asset), regardless of whether it holds other assets. The check is funding.length === 0 after getAllCoins(account, baseAssetId).
Common situations: Fresh account never funded with base asset; account drained by prior transactions; wrong account selected for consolidation; baseAssetId mismatch between provider config and the asset the account actually holds; test that funds only non-base assets.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/a44652fc9d89e88b.
Report an issue: GitHub.