FuelLabs/fuel-core · error
Unable to add more `Change` outputs because reached the maxi
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.
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)
Solutions
- Set changePolicy to Destroy for assets whose change you do not need back (no Change output is created)
- Reduce pre-existing outputs in the tx or the number of distinct assets in requiredBalances
- 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
- Use ChangePolicy::Destroy for assets whose remainder you can burn
- Each distinct asset in inputs produces one Change output — budget for it
- Split multi-asset sweeps into per-asset transactions
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
- The transaction has more outputs than allowed by the consens
- The asset {} has multiple change policies
- Filling required balances occupies a number of inputs more t
- Unable to add more inputs because reached the maximum allowe
- The fee address index is out of bounds
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/b95a7d286518d591.
Report an issue: GitHub.