FuelLabs/fuels-ts · error · FuelError

ENCODE_ERROR

ENCODE_ERROR

Error message

Expected array value.

What it means

Thrown by `ArrayCoder.encode` (code `ENCODE_ERROR`) when the value passed for a Sway fixed-size array type is not a JavaScript array. Sway arrays (`[T; N]`) must be encoded from an ordered JS array; anything else (object, string, number, BN) is rejected up front.

Source

Thrown at packages/abi-coder/src/encoding/coders/ArrayCoder.ts:30

export class ArrayCoder<TCoder extends Coder> extends Coder<
  InputValueOf<TCoder>,
  DecodedValueOf<TCoder>
> {
  coder: TCoder;
  length: number;
  #hasNestedOption: boolean;

  constructor(coder: TCoder, length: number) {
    super('array', `[${coder.type}; ${length}]`, length * coder.encodedLength);
    this.coder = coder;
    this.length = length;
    this.#hasNestedOption = hasNestedOption([coder]);
  }

  encode(value: InputValueOf<TCoder>): Uint8Array {
    if (!Array.isArray(value)) {
      throw new FuelError(ErrorCode.ENCODE_ERROR, `Expected array value.`);
    }

    if (this.length !== value.length) {
      throw new FuelError(ErrorCode.ENCODE_ERROR, `Types/values length mismatch.`);
    }

    return concat(Array.from(value).map((v) => this.coder.encode(v)));
  }

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

    let newOffset = offset;
    const decodedValue = Array(this.length)
      .fill(0)
      .map(() => {

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Pass a plain JS array: `[v1, v2, ...]`.
  2. If you have an array-like object, convert with `Array.from(obj)` first.
  3. Let generated TypeScript types guide construction instead of bypassing with `as any`.

Example fix

// before — ABI: function foo([u64; 2])
await contract.functions.foo({ 0: 1, 1: 2 }).call();
// after
await contract.functions.foo([1, 2]).call();
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Array.isArray(value)) {
  throw new TypeError(`Expected an array for [T; N] input, got ${typeof value}`);
}

Type guard

function isArrayValue(value) {
  return Array.isArray(value);
}

Try / catch

try {
  arrayCoder.encode(value);
} catch (e) {
  if (e.code === 'ENCODE_ERROR' && /Expected array value/.test(e.message)) {
    value = Array.from(value); // attempt normalize, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Passing an object `{0: .., 1: ..}` or a `Uint8Array`-typed value where a plain array is expected; passing a single value where the ABI declares `[T; N]`; bypassing TS types with `as any`.

Common situations: Serializing from JSON that produced array-like objects instead of arrays; mixing up `Vec<T>` (which maps differently) and `[T; N]`; using a Set/Map where an array was expected.

Related errors


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