FuelLabs/fuels-ts · error · FuelError

DECODE_ERROR

DECODE_ERROR

Error message

Invalid struct data size.

What it means

Thrown by StructCoder.decode() when the struct has no nested Option fields and the data buffer is shorter than the struct's total encoded length (sum of all field encoded lengths). Without nested Options the struct is fixed-size, so the buffer must be at least that large. Structs with nested Option fields skip this check because Option encoding is variable-length.

Source

Thrown at packages/abi-coder/src/encoding/coders/StructCoder.ts:56

      Object.keys(this.coders).map((fieldName) => {
        const fieldCoder = this.coders[fieldName];
        const fieldValue = value[fieldName];

        if (!(fieldCoder instanceof OptionCoder) && fieldValue == null) {
          throw new FuelError(
            ErrorCode.ENCODE_ERROR,
            `Invalid ${this.type}. Field "${fieldName}" not present.`
          );
        }

        return fieldCoder.encode(fieldValue);
      })
    );
  }

  decode(data: Uint8Array, offset: number): [DecodedValueOf<TCoders>, number] {
    if (!this.#hasNestedOption && data.length < this.encodedLength) {
      throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid struct data size.`);
    }

    let newOffset = offset;
    const decodedValue = Object.keys(this.coders).reduce((obj, fieldName) => {
      const fieldCoder = this.coders[fieldName];
      let decoded;
      [decoded, newOffset] = fieldCoder.decode(data, newOffset);

      // eslint-disable-next-line no-param-reassign
      obj[fieldName as keyof DecodedValueOf<TCoders>] = decoded;
      return obj;
    }, {} as DecodedValueOf<TCoders>);

    return [decodedValue, newOffset];
  }
}

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Verify data.length >= structCoder.encodedLength before calling decode().
  2. Ensure the struct coder matches the ABI struct definition exactly.
  3. Check for data truncation in the pipeline.

Example fix

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

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

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Decoding a truncated buffer that does not contain enough bytes for all struct fields. ABI mismatch where the struct layout differs between encoder and decoder. Using the wrong struct coder for the data format.

Common situations: Malformed RPC data. ABI version mismatch between contract and client. Manual data construction with incorrect sizing.

Related errors


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