TheAlgorithms/JavaScript · error · Error

${creditCardString} is an invalid credit card number because

Error message

${creditCardString} is an invalid credit card number because of its first two digits.

What it means

Thrown by validateCreditCard() when the string passes type, NaN, and length checks but does not start with one of the recognized Issuer Identification Number prefixes: '4' (Visa), '5' (Mastercard), '6' (Discover), '37','34','35' (Amex). A generic Error signalling the issuer could not be matched.

Source

Thrown at String/ValidateCreditCard.js:54

  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)) {
    throw new Error(errorMessage + 'it fails the Luhn check.')
  }

  return true
}

export { validateCreditCard }

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. Check the prefix against the recognized list ['4','5','6','37','34','35'] and either accept the rejection or extend validStartSubString in your own fork.
  2. For tests, use a number whose prefix is on the list (e.g. Visa-style '4...').
  3. If you must support other issuers (UnionPay, JCB '35' already supported, etc.), wrap or fork the function and extend validStartSubString.
  4. Verify you are not double-trimming digits from the start during sanitization.

Example fix

// before
validateCreditCard('6221260000000000') // UnionPay '62' not recognized

// after (if you control the function)
const validStartSubString = ['4', '5', '6', '37', '34', '35', '62']
// or: use a test card with a recognized prefix
validateCreditCard('4111111111111111')
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_PREFIXES = ['4','5','6','37','34','35']
function hasKnownIssuer(s) {
  return KNOWN_PREFIXES.some((p) => s.startsWith(p))
}
// call hasKnownIssuer(digits) before validateCreditCard

Type guard

const hasKnownIssuerPrefix = (s) => ['4','5','6','37','34','35'].some((p) => typeof s === 'string' && s.startsWith(p))

Try / catch

try { validateCreditCard(card) } catch (e) { if (/first two digits/.test(e.message)) { /* unsupported or unknown issuer */ } else throw e }

Prevention

When it happens

Trigger: Calling validateCreditCard with a string starting with '3' but not '34','35','37' (e.g. '3012345678901234' — Diners/JCB not in the list); starting with '1' or '2'; starting with '6011' (Discover uses '6' prefix so this passes); a valid-Luhn synthetic test number that uses an unrecognized prefix.

Common situations: Test fixtures using Luhn-valid numbers from issuers not on the list (e.g. UnionPay '62', JCB '35' — note 35 IS in the list); card networks added since the function was written; typos in the first digits; using a generated test card the library does not recognize.

Related errors


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