FuelLabs/fuels-ts · error · FuelError

DECODE_ERROR

DECODE_ERROR

Error message

Invalid tuple data size.

What it means

Thrown by TupleCoder.decode() when the tuple has no nested Option fields and the data buffer is shorter than the tuple's total encoded length (sum of all element coder lengths). Without nested Options the tuple is fixed-size, so the buffer must be at least that large. Tuples with nested Option fields skip this check.

Source

Thrown at packages/abi-coder/src/encoding/coders/TupleCoder.ts:40

  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;
    });

    return [decodedValue as DecodedValueOf<TCoders>, newOffset];
  }
}

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Verify data.length >= tupleCoder.encodedLength before calling decode().
  2. Ensure the tuple coder matches the ABI tuple definition.
  3. Check for data truncation in transit.

Example fix

// before
tupleCoder.decode(truncatedData, 0); // throws DECODE_ERROR

// after
if (data.length < tupleCoder.encodedLength) {
  throw new Error(`Need ${tupleCoder.encodedLength} bytes, got ${data.length}`);
}
tupleCoder.decode(data, 0);
Defensive patterns

Strategy: validation

Validate before calling

function canDecodeTuple(data: Uint8Array, encodedLength: number): boolean {
  return data.length >= encodedLength;
}

Prevention

When it happens

Trigger: Decoding a truncated buffer that does not contain all tuple elements' bytes. ABI mismatch. Using the wrong tuple coder for the data format.

Common situations: Malformed data from an RPC response. ABI version mismatch. Incorrect buffer slicing before decode.

Related errors


AI-assisted analysis of FuelLabs/fuels-ts@b3f37c91ac (2026-08-12). Data as JSON: /api/errors/882c02c9e9328859. Report an issue: GitHub.