FuelLabs/fuels-ts · error · FuelError
ENCODE_ERROR
ENCODE_ERROR
Error message
Types/values length mismatch.
What it means
Thrown by TupleCoder.encode() when the number of values in the input array does not match the number of coders in the tuple type. A Sway tuple (A, B, C) expects exactly 3 values; providing fewer or more triggers this error. TupleCoder has a fixed arity defined at construction time.
Source
Thrown at packages/abi-coder/src/encoding/coders/TupleCoder.ts:32
};
export class TupleCoder<TCoders extends Coder[]> extends Coder<
InputValueOf<TCoders>,
DecodedValueOf<TCoders>
> {
coders: TCoders;
#hasNestedOption: boolean;
constructor(coders: TCoders) {
const encodedLength = coders.reduce((acc, coder) => acc + coder.encodedLength, 0);
super('tuple', `(${coders.map((coder) => coder.type).join(', ')})`, encodedLength);
this.coders = coders;
this.#hasNestedOption = hasNestedOption(coders);
}
encode(value: InputValueOf<TCoders>): Uint8Array {
if (this.coders.length !== value.length) {
throw new FuelError(ErrorCode.ENCODE_ERROR, `Types/values length mismatch.`);
}
return concatBytes(this.coders.map((coder, i) => coder.encode(value[i])));
}
decode(data: Uint8Array, offset: number): [DecodedValueOf<TCoders>, number] {
if (!this.#hasNestedOption && data.length < this.encodedLength) {
throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid tuple data size.`);
}
let newOffset = offset;
const decodedValue = this.coders.map((coder) => {
let decoded;
[decoded, newOffset] = coder.decode(data, newOffset);
return decoded;
});
View on GitHub (pinned to b3f37c91ac)
Solutions
- Match the value array length to the tuple's element count.
- Update the client when the ABI tuple arity changes.
- Use TypeScript tuple types ([A, B, C]) to enforce arity at compile time.
Example fix
// before
const coder = new TupleCoder([new NumberCoder('u32'), new BooleanCoder()]);
coder.encode([1]); // throws ENCODE_ERROR, expected 2 values
// after
coder.encode([1, true]); Defensive patterns
Strategy: validation
Validate before calling
function matchesTupleArity(values: unknown[], expectedLength: number): boolean {
return Array.isArray(values) && values.length === expectedLength;
} Type guard
function isTupleOfArity<T extends unknown[]>(value: unknown, arity: number): value is T {
return Array.isArray(value) && value.length === arity;
} Prevention
- Use TypeScript tuple types ([A, B, C]) not arrays (A[]) for tuple values.
- Validate arity against the ABI before encoding.
- When the ABI tuple changes, regenerate client types.
When it happens
Trigger: ABI declares tuple (u32, bool, b256) but the caller passes [42] or [42, true, addr, extra]. Constructing tuple values from variable-length data without enforcing arity. Forgetting one element when building the tuple value.
Common situations: ABI tuple type changed but client code not updated. Dynamic data with variable arity passed to a fixed-arity tuple coder. Misunderstanding of tuple vs array semantics.
Related errors
AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12).
Data as JSON: /api/errors/f571dc5e5733835c.
Report an issue: GitHub.