TheAlgorithms/JavaScript · error · TypeError

Not a valid character: ${digit}

Error message

Not a valid character: ${digit}

What it means

Thrown by convertArbitraryBase during digit decoding when a character in stringInBaseOne is not present in baseOneCharacterString (indexOf returns -1). The interpolated ${digit} names the offending character. It protects the arithmetic from producing a silently wrong value (indexOf -1 would otherwise be treated as the last digit).

Source

Thrown at Conversions/ArbitraryBase.js:51

  const baseOneCharacters = [...baseOneCharacterString]
  const baseTwoCharacters = [...baseTwoCharacterString]

  for (const charactersInBase of [baseOneCharacters, baseTwoCharacters]) {
    if (charactersInBase.length !== new Set(charactersInBase).size) {
      throw new TypeError(
        'Duplicate characters in character set are not allowed'
      )
    }
  }
  const reversedStringOneChars = [...stringInBaseOne].reverse()
  const stringOneBase = baseOneCharacters.length
  let value = 0
  let placeValue = 1
  for (const digit of reversedStringOneChars) {
    const digitNumber = baseOneCharacters.indexOf(digit)
    if (digitNumber === -1) {
      throw new TypeError(`Not a valid character: ${digit}`)
    }
    value += digitNumber * placeValue
    placeValue *= stringOneBase
  }
  const outputChars = []
  const stringTwoBase = baseTwoCharacters.length
  while (value > 0) {
    const [divisionResult, remainder] = floorDiv(value, stringTwoBase)
    outputChars.push(baseTwoCharacters[remainder])
    value = divisionResult
  }
  return outputChars.reverse().join('') || baseTwoCharacters[0]
}

/**
 * Converts a arbitrary-length string from one base to other. Doesn't lose accuracy.
 * @param {string} stringInBaseOne String in input base
 * @param {string} baseOneCharacters Character set for the input base

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. Trim and normalize the input string's case to match baseOneCharacterString before calling.
  2. Verify each character of the input exists in the source alphabet with a pre-check.
  3. Re-confirm the source alphabet actually contains all glyphs that appear in your input data.

Example fix

// before
convertArbitraryBase('1A', '0123456789', '01')
// after
convertArbitraryBase('1A', '0123456789ABCDEF', '01')
Defensive patterns

Strategy: validation

Validate before calling

const srcSet = new Set([...srcAlpha])
const allValid = [...input].every((ch) => srcSet.has(ch))
if (!allValid) {
  throw new Error('Input contains characters outside the source alphabet')
}
convertArbitraryBase(input, srcAlpha, dstAlpha)

Type guard

const inputWithinAlphabet = (input, alpha) =>
  [...input].every((ch) => alpha.includes(ch))

Try / catch

try {
  convertArbitraryBase(input, srcAlpha, dstAlpha)
} catch (e) {
  if (/Not a valid character/.test(e.message)) {
    const bad = e.message.replace('Not a valid character: ', '')
    // log/strip/normalize the offending glyph, then retry or report
  }
  throw e
}

Prevention

When it happens

Trigger: Calling convertArbitraryBase('1A', '0123456789', '01') — 'A' is not in the decimal alphabet; passing lowercase digits into an uppercase alphabet; invisible characters like a leading/trailing space or a zero-width space sneaking into the input string.

Common situations: Mismatched case between input and alphabet (e.g. hex input 'ff' against alphabet '0123456789ABCDEF'); whitespace from untrimmed user input; copy-paste introducing a non-breaking space; using the wrong source alphabet for the data.

Related errors


AI-assisted analysis of TheAlgorithms/JavaScript@5c39e87a9a (2026-08-13). Data as JSON: /api/errors/6f89cddf45ee89b8. Report an issue: GitHub.