FuelLabs/fuels-ts · warning · FuelError
NO_COINS_TO_CONSOLIDATE
NO_COINS_TO_CONSOLIDATE
Error message
No coins to consolidate.
What it means
Thrown by validateConsolidationTxsCoins when the supplied coin array has 0 or 1 entries. Consolidation merges many UTXOs into fewer ones; with a single coin there is nothing to consolidate, so the SDK aborts rather than build a no-op transaction that still costs gas. Called from assembleBaseAssetConsolidationTxs and assembleNonBaseAssetConsolidationTxs.
Source
Thrown at packages/account/src/account.ts:1275
return await assembleTx();
}
}
/** @hidden * */
private validateTransferAmount(amount: BigNumberish) {
if (bn(amount).lte(0)) {
throw new FuelError(
ErrorCode.INVALID_TRANSFER_AMOUNT,
'Transfer amount must be a positive number.'
);
}
}
/** @hidden * */
private validateConsolidationTxsCoins(coins: Coin[], assetId: string) {
if (coins.length <= 1) {
throw new FuelError(ErrorCode.NO_COINS_TO_CONSOLIDATE, 'No coins to consolidate.');
}
if (!coins.every((c) => c.assetId === assetId)) {
throw new FuelError(
ErrorCode.COINS_ASSET_ID_MISMATCH,
'All coins to consolidate must be from the same asset id.'
);
}
}
/** @hidden * */
private async setTransactionStateForConnectors(params: {
transactionRequest: TransactionRequest;
connectorOptions: AccountSendTxParams;
}): Promise<{
transactionRequest: TransactionRequest;
connectorsSendTxParams: FuelConnectorSendTxParams;
}> {View on GitHub (pinned to b3f37c91ac)
Solutions
- Check the UTXO count for the asset before consolidating and skip if <= 1: const coins = await provider.getCoins(account, assetId); if (coins.length > 1) await account.consolidateCoins({ assetId });.
- Wrap the call in a try/catch for NO_COINS_TO_CONSOLIDATE and treat it as an expected no-op.
- Re-fetch coins right before consolidation rather than trusting a stale count.
Example fix
// before
await account.consolidateCoins({ assetId });
// after
const { coins } = await provider.getCoins(account.address, assetId);
if (coins.length > 1) {
await account.consolidateCoins({ assetId });
} Defensive patterns
Strategy: validation
Validate before calling
// Only consolidate when there is more than one UTXO
const { coins } = await provider.getCoins(account.address, assetId);
if (coins.length > 1) {
await account.consolidateCoins({ assetId });
} Type guard
function hasMultipleCoins(coins: Coin[]): boolean {
return coins.length > 1;
} Try / catch
try {
await account.consolidateCoins({ assetId });
} catch (e) {
if (e instanceof FuelError && e.code === ErrorCode.NO_COINS_TO_CONSOLIDATE) {
// expected no-op; nothing to consolidate
} else throw e;
} Prevention
- Pre-fetch the UTXO count for the asset and skip consolidation when <= 1.
- Treat NO_COINS_TO_CONSOLIDATE as an expected condition, not a fatal error.
- Avoid calling consolidate in a tight loop that drives the UTXO set to one.
When it happens
Trigger: Calling account.consolidateCoins({ assetId }) (or the assemble*ConsolidationTxs methods) when the account has only one UTXO (or none) for that asset, or passing a pre-fetched coins array of length <= 1.
Common situations: Consolidating on a fresh or recently-swept wallet that has one UTXO left, calling consolidate repeatedly until only one UTXO remains, or filtering coins down to a single element before consolidation.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/3d64bcd81b743da8.
Report an issue: GitHub.