FuelLabs/fuel-core · error

Unable to add more `Change` outputs because reached the…

Error message

Unable to add more `Change` outputs because reached the maximum allowed outputs limit

What it means

For every new asset seen in the added inputs, the assembler creates a Change output (unless the policy is Destroy) and checks the tx stays within tx_params.max_outputs. The error fires when adding those Change outputs would exceed the output limit.

Solutions

  1. Set changePolicy to Destroy for assets whose change you do not need back (no Change output is created)
  2. Reduce pre-existing outputs in the tx or the number of distinct assets in requiredBalances
  3. Split into several single-asset transactions

Example fix

// before
await client.assembleTx(txBytes, {
  requiredBalances: assets.map((a) => ({ account, assetId: a, changeAccount: account })),
});

// after
await client.assembleTx(txBytes, {
  requiredBalances: assets.map((a) => ({
    account,
    assetId: a,
    changeAccount: null, // Destroy policy: no Change output per asset
  })),
});
Defensive patterns

Strategy: validation

Validate before calling

const distinctAssets = new Set(requiredBalances.map(b => b.assetId)).size;
if (tx.outputs.length + distinctAssets > maxOutputs) {
  throw new Error(`output budget exceeded: ${tx.outputs.length} + ${distinctAssets} change outputs > ${maxOutputs}`);
}

Try / catch

catch (e) { if (/reached the maximum allowed outputs limit/.test(e.message)) { /* set changePolicy destroy for unneeded assets or reduce outputs */ } else throw e; }

Prevention

When it happens

Trigger: Inputs added for required balances or fee introduce more distinct asset ids than there are free output slots, given the outputs already in your tx.

Common situations: Multi-asset transactions where every touched asset needs a Change output on top of pre-existing outputs; scripts with many pre-declared Variable outputs; chains with lowered max_outputs.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/b95a7d286518d591. Report an issue: GitHub.

Appendix: source

Thrown at crates/fuel-core/src/schema/tx/assemble_tx.rs:566

                    ChangePolicy::Change(self.fee_payer_account.owner())
                };

            match change_policy {
                ChangePolicy::Change(change_receiver) => {
                    self.tx.outputs_mut().push(Output::change(
                        change_receiver,
                        0,
                        asset_id,
                    ));

                    let max_outputs = self
                        .arguments
                        .consensus_parameters
                        .tx_params()
                        .max_outputs();

                    if self.tx.outputs().len() > max_outputs as usize {
                        return Err(anyhow::anyhow!(
                            "Unable to add more `Change` outputs \
                            because reached the maximum allowed outputs limit"
                        ));
                    }
                }
                ChangePolicy::Destroy => {
                    // Do nothing for now, since `fuel-tx` crate doesn't have
                    // `Destroy` output yet.
                    // https://github.com/FuelLabs/fuel-specs/issues/621
                }
            }
        }

        Ok(())
    }

    fn is_runnable_script(&self) -> bool {
        if let Some(script) = self.tx.as_script()

View on GitHub (pinned to b9d4d170da)