TheAlgorithms/JavaScript · error · Error
${creditCardString} is an invalid credit card number because
Error message
${creditCardString} is an invalid credit card number because it fails the Luhn check. What it means
Thrown by validateCreditCard() when the string passes type, NaN, length, and prefix checks but fails the Luhn checksum (luhnValidation returns false). The Luhn algorithm sums digits with every second digit doubled-and-split; failing means a typo or fabricated number. Generic Error, not TypeError.
Source
Thrown at String/ValidateCreditCard.js:57
}
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
- Verify the number against an independent Luhn tool; recompute the check digit if generating test data.
- Have the user re-enter the number; surface a 'Please check your card number’ message.
- When generating fixtures, derive the last digit using the Luhn algorithm so the number is valid.
- Confirm sanitization did not drop or duplicate a digit before validation.
Example fix
// before
validateCreditCard('4111111111111112') // wrong check digit
// after
validateCreditCard('4111111111111111') // Luhn-valid Visa test number Defensive patterns
Strategy: validation
Validate before calling
function luhnValid(s) {
let sum = 0, alt = false
for (let i = s.length - 1; i >= 0; i--) {
let d = parseInt(s[i], 10)
if (alt) { d *= 2; if (d > 9) d -= 9 }
sum += d; alt = !alt
}
return sum % 10 === 0
}
// call luhnValid(digits) before validateCreditCard to pre-empt Type guard
const passesLuhn = (s) => typeof s === 'string' && /^\d+$/.test(s) && luhnValid(s)
Try / catch
try { validateCreditCard(card) } catch (e) { if (/Luhn check/.test(e.message)) { /* ask user to re-check the number */ } else throw e } Prevention
- Generate test fixtures with a correctly computed Luhn check digit.
- Surface a generic 'please re-enter your card number' message on this failure.
- Detect transpositions and single-digit typos client-side using Luhn before submit.
When it happens
Trigger: Calling validateCreditCard('49927398716') would fail length first; for a length- and prefix-valid number like '4111111111111112' (last digit changed), luhnValidation returns false and this throws. Transposing two adjacent digits, or flipping a single digit, usually breaks Luhn.
Common situations: User mistyped a digit; generated test numbers without computing the Luhn check digit; copy-paste that dropped or duplicated a digit; intentionally using an invalid number to test the error path.
Related errors
- ${creditCardString} is an invalid credit card number because
- ${creditCardString} is an invalid credit card number because
- The given value is not a string
- ${creditCardString} is an invalid credit card number because
- Invalid day value.
AI-assisted analysis of TheAlgorithms/JavaScript@5c39e87a9a (2026-08-13).
Data as JSON: /api/errors/c96ac1e3660024e1.
Report an issue: GitHub.