FuelLabs/fuels-ts · error · FuelError
DECODE_ERROR
DECODE_ERROR
Error message
Types/values length mismatch during decode. ${JSON.stringify({ count: { types: this.jsonFn.inputs.length, nonVoidInputs: nonVoidInputs.length, values: bytes.length }, value: { args: this.jsonFn.inputs, nonVoidInputs, values: bytes } })} What it means
Thrown by `FunctionFragment.decodeArguments` (code `DECODE_ERROR`) when a function has zero non-void inputs (so its encoded call arguments should be empty) but the byte buffer passed in is non-empty. The message dumps counts and the raw bytes to aid diagnosis. This is the decode counterpart of the encode path and signals that the bytes do not correspond to this function's input shape.
Source
Thrown at packages/abi-coder/src/FunctionFragment.ts:88
encoding: this.encoding,
})
);
const argumentValues = padValuesWithUndefined(values, this.jsonFn.inputs);
return new TupleCoder(coders).encode(argumentValues);
}
decodeArguments(data: BytesLike) {
const bytes = arrayify(data);
const nonVoidInputs = findNonVoidInputs(this.jsonAbiOld, this.jsonFnOld.inputs);
if (nonVoidInputs.length === 0) {
// The VM is current return 0x0000000000000000, but we should treat it as undefined / void
if (bytes.length === 0) {
return undefined;
}
throw new FuelError(
ErrorCode.DECODE_ERROR,
`Types/values length mismatch during decode. ${JSON.stringify({
count: {
types: this.jsonFn.inputs.length,
nonVoidInputs: nonVoidInputs.length,
values: bytes.length,
},
value: {
args: this.jsonFn.inputs,
nonVoidInputs,
values: bytes,
},
})}`
);
}
const result = this.jsonFnOld.inputs.reduce(
(obj: { decoded: unknown[]; offset: number }, input) => {View on GitHub (pinned to b3f37c91ac)
Solutions
- Confirm the bytes were produced for the same function fragment you are decoding against.
- Regenerate bindings from the deployed contract's ABI and retry.
- If the function genuinely has no inputs, ensure you pass an empty buffer (`0x` or `new Uint8Array(0)`).
- Inspect the dumped `count`/`value` in the message to compare expected inputs vs. actual bytes.
Example fix
// before
const [, returned] = contractInterface.decodeFunctionResult('noArgFn', someBytes);
// after — verify the bytes belong to this function; pass empty if no inputs
const [, returned] = contractInterface.decodeFunctionResult('noArgFn', '0x'); Defensive patterns
Strategy: try-catch
Validate before calling
const nonVoidInputs = findNonVoidInputs(iface.jsonAbiOld, fn.inputs);
if (nonVoidInputs.length === 0 && arrayify(data).length > 0) {
// bytes do not belong to this no-arg function; don't call decode
console.warn('Ignoring non-empty bytes for void-input function');
} Try / catch
try {
const decoded = fragment.decodeArguments(data);
} catch (e) {
if (e.code === 'DECODE_ERROR' && /Types\/values length mismatch during decode/.test(e.message)) {
// ABI/bytes mismatch — regenerate bindings or pass empty buffer for no-input fns
}
throw e;
} Prevention
- Keep the ABI in sync with the deployed contract; regenerate after every contract change.
- Match the exact function fragment to the bytes you decode.
- For functions with no inputs, pass an empty buffer (`'0x'`).
When it happens
Trigger: Decoding a return/script-data blob against a function whose ABI declares only void inputs but passing a non-empty buffer; pairing the wrong function fragment with bytes from a different function; ABI/bytecode drift where the contract emits call data the ABI does not model.
Common situations: Reusing a cached ABI after the contract was redeployed with new inputs; decoding transaction script data with a mismatched script ABI; feeding the result of one function into the decoder of another.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/3a34e17e86063692.
Report an issue: GitHub.