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

  1. Match the value array length to the tuple's element count.
  2. Update the client when the ABI tuple arity changes.
  3. 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

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.