FuelLabs/fuels-ts · error · FuelError

ENCODE_ERROR

ENCODE_ERROR

Error message

Invalid ${this.type} type - number value is too large. Number can only safely handle up to 53 bits.

What it means

Thrown by BigNumberCoder.encode (u64 or u256; this.type is the baseType) when typeof value === 'number' and value > Number.MAX_SAFE_INTEGER (2^53 - 1). The full message reads "Invalid <u64|u256> type - number value is too large. Number can only safely handle up to 53 bits.". The library refuses JS numbers beyond safe-integer range because they silently lose precision, which would corrupt on-chain amounts.

Source

Thrown at packages/abi-coder/src/encoding/coders/BigNumberCoder.ts:27

const encodedLengths: { [key in BigNumberCoderType]: number } = {
  u64: WORD_SIZE,
  u256: WORD_SIZE * 4,
};

export class BigNumberCoder extends Coder<BNInput, BN> {
  constructor(baseType: BigNumberCoderType) {
    super('bigNumber', baseType, encodedLengths[baseType]);
  }

  encode(value: BNInput): Uint8Array {
    let bytes;

    // We throw an error if the value is a number and it's more than the max safe integer
    // This is because we can experience some odd behavior with integers more than the max safe integer
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER#description
    if (typeof value === 'number' && value > Number.MAX_SAFE_INTEGER) {
      throw new FuelError(
        ErrorCode.ENCODE_ERROR,
        `Invalid ${this.type} type - number value is too large. Number can only safely handle up to 53 bits.`
      );
    }

    try {
      bytes = toBytes(value, this.encodedLength);
    } catch (error) {
      throw new FuelError(ErrorCode.ENCODE_ERROR, `Invalid ${this.type}.`);
    }

    return bytes;
  }

  decode(data: Uint8Array, offset: number): [BN, number] {
    if (data.length < this.encodedLength) {
      throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid ${this.type} data size.`);
    }

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Pass the value as a string (e.g. '9007199254740992') or a BN, not a number.
  2. Keep large amounts as strings end-to-end (config, API responses, inputs).
  3. If you must compute, use bn() and do arithmetic on BN objects.
  4. Add a guard that converts any number > MAX_SAFE_INTEGER to a string before encode.

Example fix

// before
bigNumberCoder.encode(10 ** 18) // > MAX_SAFE_INTEGER → throws

// after
bigNumberCoder.encode('1000000000000000000') // string is safe
Defensive patterns

Strategy: validation

Validate before calling

if (typeof value === 'number' && value > Number.MAX_SAFE_INTEGER) {
  throw new Error('value too large for a JS number; pass a string or BN')
}
bigNumberCoder.encode(value)

Type guard

const isSafeNumberOrString = (v: unknown): boolean =>
  typeof v !== 'number' || v <= Number.MAX_SAFE_INTEGER

Try / catch

try { bigNumberCoder.encode(value) }
catch (e) { if ((e as FuelError).code === ErrorCode.ENCODE_ERROR) { /* convert to string/BN and retry */ } throw e }

Prevention

When it happens

Trigger: Calling new BigNumberCoder('u64').encode(amount) — or encoding a u64/u256 Sway function argument — with a plain JS number greater than 9007199254740991. Common with token amounts, block numbers scaled up, or computed products of large numbers.

Common situations: Passing wei-like token amounts as Number instead of string/BN; arithmetic that overflows safe integer range; values read from JSON as numbers instead of strings; misunderstanding that u64/u256 can exceed 53 bits.

Related errors


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