FuelLabs/fuels-ts · error · FuelError
SCRIPT_REVERTED
SCRIPT_REVERTED
Error message
Transaction reverted.
What it means
Thrown by the contract multicall script decoder when the wrapper script exits with a non-zero code, meaning one of the batched contract calls reverted on-chain. The SDK wraps multicalls in a script; a non-zero script exit signals an abort/revert inside the Sway execution of one of the calls.
Source
Thrown at packages/program/src/contract-call-script.ts:114
}
type ReturnReceipt = TransactionResultReturnReceipt | TransactionResultReturnDataReceipt;
const isReturnType = (type: ReturnReceipt['type']) =>
type === ReceiptType.Return || type === ReceiptType.ReturnData;
const getMainCallReceipt = (
receipts: TransactionResultCallReceipt[],
contractId: string
): TransactionResultCallReceipt | undefined =>
receipts.find(
({ type, id, to }) =>
type === ReceiptType.Call && id === SCRIPT_WRAPPER_CONTRACT_ID && to === contractId
);
const scriptResultDecoder = (contractId: Address) => (result: ScriptResult) => {
if (toNumber(result.code) !== 0) {
throw new FuelError(ErrorCode.SCRIPT_REVERTED, `Transaction reverted.`);
}
const mainCallResult = getMainCallReceipt(
result.receipts as TransactionResultCallReceipt[],
contractId.toB256()
);
const mainCallInstructionStart = bn(mainCallResult?.is);
const receipts = result.receipts as ReturnReceipt[];
return receipts
.filter(({ type }) => isReturnType(type))
.flatMap((receipt: ReturnReceipt) => {
if (!mainCallInstructionStart.eq(bn(receipt.is))) {
return [];
}
if (receipt.type === ReceiptType.Return) {
return [new BigNumberCoder('u64').encode((receipt as TransactionResultReturnReceipt).val)];
}View on GitHub (pinned to b3f37c91ac)
Solutions
- Inspect the transaction receipts (especially Revert and Log receipts) for the Sway revert reason / revert code.
- Re-run the call with higher gas or via dryRun to see the exact failure.
- Verify the contract arguments and ABI match the deployed code.
- Reproduce with a single call to isolate which entry in a multicall reverted.
Example fix
// before
const { value } = await contract.functions.foo(args).call();
// after — dry-run and inspect receipts
const scope = contract.functions.foo(args);
const dry = await scope.dryRun();
console.log(dry.receipts); // look for ReceiptType.Revert / Log
const { value } = await scope.call(); Defensive patterns
Strategy: try-catch
Validate before calling
// dry-run first to surface the revert reason without submitting
const dryRunResult = await contract.functions.foo(args).dryRun();
const reverted = dryRunResult.receipts.some((r) => r.type === ReceiptType.Revert);
if (reverted) throw new Error('call would revert on-chain'); Type guard
const isScriptReverted = (e: unknown): boolean => e instanceof FuelError && e.code === FuelError.CODES.SCRIPT_REVERTED;
Try / catch
try {
return await contract.functions.foo(args).call();
} catch (e) {
if (e instanceof FuelError && e.code === FuelError.CODES.SCRIPT_REVERTED) {
// inspect tx receipts / logs for the Sway revert reason
}
throw e;
} Prevention
- Dry-run calls during development to catch reverts before submitting.
- Keep ABI and deployed bytecode in sync; mismatches cause silent reverts.
- Provide adequate gas; underfunded scripts revert mid-execution.
When it happens
Trigger: Calling a contract function (especially via multicall) where the Sway code hits an `assert`/`revert`/`abort`, runs out of gas, or receives invalid arguments that fail a require.
Common situations: Contract precondition failure (e.g. insufficient allowance, wrong owner, invalid state), gas estimation too low causing mid-script revert, swapped argument order, ABI/code mismatch after redeploy.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/6df77ef1fd60d9bf.
Report an issue: GitHub.