TheAlgorithms/JavaScript · error · TypeError

The given value is not a string

Error message

The given value is not a string

What it means

Thrown by validateCreditCard() in String/ValidateCreditCard.js when typeof creditCardString !== 'string'. A TypeError raised before any digit/length/Luhn checks, because the function then reads .length and .startsWith on the value. The card number is expected as a string to preserve leading zeros and to allow prefix checks.

Source

Thrown at String/ValidateCreditCard.js:38

      // Multiply every 2nd digit from the left by 2
      currentDigit *= 2
      // if product is greater than 10 add the individual digits of the product to get a single digit
      if (currentDigit > 9) {
        currentDigit %= 10
        currentDigit += 1
      }
    }
    validationSum += currentDigit
  })

  return validationSum % 10 === 0
}

const validateCreditCard = (creditCardString) => {
  const validStartSubString = ['4', '5', '6', '37', '34', '35'] // Valid credit card numbers start with these numbers

  if (typeof creditCardString !== 'string') {
    throw new TypeError('The given value is not a string')
  }

  const errorMessage = `${creditCardString} is an invalid credit card number because `
  if (isNaN(creditCardString)) {
    throw new TypeError(errorMessage + 'it has nonnumerical characters.')
  }
  const creditCardStringLength = creditCardString.length
  if (!(creditCardStringLength >= 13 && creditCardStringLength <= 16)) {
    throw new Error(errorMessage + 'of its length.')
  }
  if (
    !validStartSubString.some((subString) =>
      creditCardString.startsWith(subString)
    )
  ) {
    throw new Error(errorMessage + 'of its first two digits.')
  }
  if (!luhnValidation(creditCardString)) {

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. Pass the card number as a string: validateCreditCard('4532015112830366').
  2. Serialize card numbers as strings at the API boundary (OpenAPI/JSON schema: type: string).
  3. If you only have a number, coerce carefully — but prefer fixing the producer; numbers above 2^53 already lost precision.
  4. Read .value from form inputs: validateCreditCard(inputEl.value).

Example fix

// before
validateCreditCard(req.body.cardNumber) // JSON parsed as Number

// after
validateCreditCard(typeof req.body.cardNumber === 'string' ? req.body.cardNumber : String(req.body.cardNumber))
// and fix the producer: send "4532015112830366" (quoted) in JSON
Defensive patterns

Strategy: type-guard

Validate before calling

function validateCardSafe(v) {
  if (typeof v !== 'string') throw new TypeError('card number must be a string')
  return validateCreditCard(v)
}

Type guard

const isCardString = (v) => typeof v === 'string' && /^\d{13,16}$/.test(v)

Try / catch

try { validateCreditCard(card) } catch (e) { if (e instanceof TypeError && /not a string/.test(e.message)) card = String(card); else throw e }

Prevention

When it happens

Trigger: Calling validateCreditCard(4532015112830366) (a Number, which loses precision beyond 2^53 and drops leading zeros), validateCreditCard(null), validateCreditCard(undefined), validateCreditCard([4,5,3,2,...]), validateCreditCard({ number: '...' }).

Common situations: Submitting card data as a JSON number instead of a string (very common API mistake); reading input from a numeric-typed form field; passing a BigInt; forgetting to read .value off a DOM input element.

Related errors


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