FuelLabs/fuels-ts · error · FuelError

INVALID_TRANSACTION_INPUT

INVALID_TRANSACTION_INPUT

Error message

Invalid transaction input type: ${type}.

What it means

Thrown by InputCoder.encode() when input.type is not one of the supported InputType enum values (Coin=0, Contract=1, Message=2). The encode switch has no case for the given type, so it falls to default. This signals an input object constructed with an out-of-range or unrecognized type.

Source

Thrown at packages/transactions/src/coders/input.ts:380

    parts.push(new NumberCoder('u8', { padToWordSize: true }).encode(value.type));

    const { type } = value;

    switch (type) {
      case InputType.Coin: {
        parts.push(new InputCoinCoder().encode(value));
        break;
      }
      case InputType.Contract: {
        parts.push(new InputContractCoder().encode(value));
        break;
      }
      case InputType.Message: {
        parts.push(new InputMessageCoder().encode(value));
        break;
      }
      default: {
        throw new FuelError(
          ErrorCode.INVALID_TRANSACTION_INPUT,
          `Invalid transaction input type: ${type}.`
        );
      }
    }

    return concat(parts);
  }

  decode(data: Uint8Array, offset: number): [Input, number] {
    let decoded;
    let o = offset;

    [decoded, o] = new NumberCoder('u8', { padToWordSize: true }).decode(data, o);
    const type = decoded as InputType;
    switch (type) {
      case InputType.Coin: {
        [decoded, o] = new InputCoinCoder().decode(data, o);

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Use the InputType enum (import { InputType }) and the SDK's input factories rather than literal numbers.
  2. Validate each input.type is one of InputType.Coin | Contract | Message before encoding.
  3. Upgrade @fuel-ts/transactions if a newer input type is required.

Example fix

// before
const input = { type: 9, ... };

// after
import { InputType } from '@fuel-ts/transactions';
const input = { type: InputType.Coin, ... };
Defensive patterns

Strategy: type-guard

Validate before calling

import { InputType } from '@fuel-ts/transactions';

const VALID_INPUT_TYPES = new Set([InputType.Coin, InputType.Contract, InputType.Message]);
function isValidInputType(t: number): boolean {
  return VALID_INPUT_TYPES.has(t as InputType);
}

inputs.forEach(i => { if (!isValidInputType(i.type)) throw new Error(`Bad input type ${i.type}`); });

Type guard

import { InputType } from '@fuel-ts/transactions';
function isValidInput(i: { type: number }): boolean {
  return [InputType.Coin, InputType.Contract, InputType.Message].includes(i.type as InputType);
}

Try / catch

try {
  inputCoder.encode(value);
} catch (e) {
  if (e instanceof FuelError && e.code === ErrorCode.INVALID_TRANSACTION_INPUT) {
    // coerce input.type to a valid InputType enum member before retrying
  } else throw e;
}

Prevention

When it happens

Trigger: Manually building an Input object with type set to an invalid number/string; passing a partial input missing a valid type; feeding a transaction request whose inputs were assembled from unvalidated data.

Common situations: Constructing raw transaction inputs without using the SDK builders; version skew where a new input type exists on-chain but the SDK does not support it; assigning type: 3+ (no such input type).

Related errors


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