{"record":{"id":"c96ac1e3660024e1","repo":"TheAlgorithms/JavaScript","slug":"creditcardstring-is-an-invalid-credit-card-numb-c96ac1","errorCode":null,"errorMessage":"${creditCardString} is an invalid credit card number because it fails the Luhn check.","messagePattern":"(.+?) is an invalid credit card number because it fails the Luhn check\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"String/ValidateCreditCard.js","lineNumber":57,"sourceCode":"  }\n\n  const errorMessage = `${creditCardString} is an invalid credit card number because `\n  if (isNaN(creditCardString)) {\n    throw new TypeError(errorMessage + 'it has nonnumerical characters.')\n  }\n  const creditCardStringLength = creditCardString.length\n  if (!(creditCardStringLength >= 13 && creditCardStringLength <= 16)) {\n    throw new Error(errorMessage + 'of its length.')\n  }\n  if (\n    !validStartSubString.some((subString) =>\n      creditCardString.startsWith(subString)\n    )\n  ) {\n    throw new Error(errorMessage + 'of its first two digits.')\n  }\n  if (!luhnValidation(creditCardString)) {\n    throw new Error(errorMessage + 'it fails the Luhn check.')\n  }\n\n  return true\n}\n\nexport { validateCreditCard }\n","sourceCodeStart":39,"sourceCodeEnd":64,"githubUrl":"https://github.com/TheAlgorithms/JavaScript/blob/5c39e87a9a31f279c60f830ad74a845e4788a517/String/ValidateCreditCard.js#L39-L64","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvalidateCreditCard('4111111111111112') // wrong check digit\n\n// after\nvalidateCreditCard('4111111111111111') // Luhn-valid Visa test number","handlingStrategy":"validation","validationCode":"function luhnValid(s) {\n  let sum = 0, alt = false\n  for (let i = s.length - 1; i >= 0; i--) {\n    let d = parseInt(s[i], 10)\n    if (alt) { d *= 2; if (d > 9) d -= 9 }\n    sum += d; alt = !alt\n  }\n  return sum % 10 === 0\n}\n// call luhnValid(digits) before validateCreditCard to pre-empt","typeGuard":"const passesLuhn = (s) => typeof s === 'string' && /^\\d+$/.test(s) && luhnValid(s)","tryCatchPattern":"try { validateCreditCard(card) } catch (e) { if (/Luhn check/.test(e.message)) { /* ask user to re-check the number */ } else throw e }","preventionTips":["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."],"tags":["validation","credit-card","luhn","checksum","business-rule"],"backgroundTag":null,"analyzedSha":"5c39e87a9a31f279c60f830ad74a845e4788a517","analyzedAt":"2026-08-13T04:54:54.474Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}