FuelLabs/fuels-ts · error · FuelError

UNKNOWN

UNKNOWN

Error message

No change output found

What it means

Internal error from createOuputCoin() in the coin-consolidation pipeline. It scans a transaction's outputs for an output whose type is OutputType.Change AND whose assetId equals the base asset id; finding none, it cannot derive the funding coin for the next consolidation batch. This is a library-internal invariant, not a user-config error.

Source

Thrown at packages/account/src/utils/consolidate-coins.ts:93

  return { coins: all };
};

/** @hidden */
const sortCoins = ({ coins }: { coins: Coin[] }) => coins.sort((a, b) => b.amount.cmp(a.amount));

/** @hidden */
const createOuputCoin = (opts: {
  transactionId: string;
  outputs: Output[];
  baseAssetId: string;
}): Coin => {
  const { transactionId, outputs, baseAssetId } = opts;

  const outputChangeIndex = outputs.findIndex(
    (output) => output.type === OutputType.Change && output.assetId === baseAssetId
  );
  if (outputChangeIndex === -1) {
    throw new FuelError(ErrorCode.UNKNOWN, 'No change output found');
  }

  const outputCoin = outputs[outputChangeIndex] as OutputChange;

  // Format the UTXO ID
  const outputIndexPadded = Number(outputChangeIndex).toString().padStart(4, '0');

  return {
    id: `${transactionId}${outputIndexPadded}`,
    assetId: outputCoin.assetId,
    amount: outputCoin.amount,
    owner: new Address(outputCoin.to),
    blockCreated: bn(0),
    txCreatedIdx: bn(0),
  };
};

export const consolidateCoins = async ({

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Do not manually strip change outputs from consolidation transactions; let consolidateCoins build them.
  2. Ensure the account has base-asset funds to cover fees so a Change output for the base asset is created.
  3. If hitting this after a SDK upgrade, check whether ScriptTransactionRequest change-variable injection behavior changed.
  4. Report as an SDK bug if reached through the public consolidateCoins API without manual intervention.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await result.submitAll();
} catch (err) {
  if (err instanceof FuelError && err.message === 'No change output found') {
    // do not retry blindly; inspect the constructed tx for missing change outputs
  }
  throw err;
}

Prevention

When it happens

Trigger: Reached via consolidateCoins -> submitAll when the previous batch's transaction result has no Change output for the base asset. This typically happens if the transaction was built without a base-asset change variable (e.g. custom ScriptTransactionRequest manipulation, or a malformed predicate flow that strips change outputs).

Common situations: Manually editing the consolidation transaction request; a chain or provider version change altering default output injection; consolidating a non-base asset where the previous tx lacked base-asset change due to zero fee; maxInputs boundary conditions producing empty batches.

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/3df9f3099b785d05. Report an issue: GitHub.