FuelLabs/fuels-ts · error · FuelError

INVALID_DATA

INVALID_DATA

Error message

invalid base58 value ${letter}

What it means

Thrown by the internal getAlpha helper in base58.ts when a character in the input string is not part of the Base58 Bitcoin alphabet (no 0, O, I, l). The Lookup table maps only the 58 valid alphabet characters to their digit values; any character absent from the table triggers the error, reporting the offending letter.

Source

Thrown at packages/utils/src/utils/base58.ts:22

import { arrayify } from './arrayify';
import type { BytesLike } from './arrayify';

const BN_0 = bn(0);
const BN_58 = bn(58);
const Alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
let Lookup: null | Record<string, BN> = null;

function getAlpha(letter: string): BN {
  if (Lookup == null) {
    Lookup = {};
    for (let i = 0; i < Alphabet.length; i++) {
      Lookup[Alphabet[i]] = bn(i);
    }
  }
  const result = Lookup[letter];
  if (result == null) {
    throw new FuelError(ErrorCode.INVALID_DATA, `invalid base58 value ${letter}`);
  }
  return bn(result);
}

/**
 *  Encode value as a Base58-encoded string.
 */
export function encodeBase58(_value: BytesLike): string {
  const bytes = arrayify(_value);

  let value = bn(bytes);
  let result = '';
  while (value.gt(BN_0)) {
    result = Alphabet[Number(value.mod(BN_58))] + result;
    value = value.div(BN_58);
  }

  // Account for leading padding zeros

View on GitHub (pinned to b3f37c91ac)

Solutions

  1. Confirm the input is genuinely Base58 (Bitcoin alphabet); strip whitespace/newlines before decoding.
  2. Replace forbidden look-alikes (0->O not valid; I, O, l are not in the alphabet) by re-reading the source address.
  3. If the value is hex or base64, decode with the appropriate utility instead of decodeBase58.
  4. Pre-validate with a regex: /^[1-9A-HJ-NP-Za-km-z]+$/.

Example fix

// before
decodeBase58('  0IJKxyz  '); // contains space, '0', 'I'

// after
const cleaned = '  0IJKxyz  '.trim();
if (!/^[1-9A-HJ-NP-Za-km-z]+$/.test(cleaned)) throw new Error('not base58');
decodeBase58(cleaned);
Defensive patterns

Strategy: validation

Validate before calling

const BASE58_RE = /^[1-9A-HJ-NP-Za-km-z]+$/;
function isBase58(v: unknown): v is string {
  return typeof v === 'string' && BASE58_RE.test(v.trim());
}
if (!isBase58(value)) throw new Error('not a base58 string');
decodeBase58(value.trim());

Type guard

const isBase58 = (v: unknown): v is string =>
  typeof v === 'string' && /^[1-9A-HJ-NP-Za-km-z]+$/.test(v);

Try / catch

try {
  const bn = decodeBase58(value);
} catch (e) {
  if (e instanceof FuelError && e.code === ErrorCode.INVALID_DATA) {
    // input wasn't base58; redirect to the correct decoder or reject
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling decodeBase58(value) where value contains a character outside '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' — e.g. '0', 'O', 'I', 'l', a space, punctuation, or any non-ASCII char. The error fires on the first such character encountered while iterating.

Common situations: Decoding a value that is actually base64, hex, or a raw string mistaken for base58. Hand-typed base58 strings containing a '0' or capital 'O'/'I' or lowercase 'l'. Whitespace/newline accidentally included in a copy-pasted address. Truncated or corrupted address from a log. Using a checksummed/modified alphabet variant.

Related errors


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