{"record":{"id":"5f1f01585511d89f","repo":"TheAlgorithms/JavaScript","slug":"invalid-phone-number","errorCode":null,"errorMessage":"Invalid phone number!","messagePattern":"Invalid phone number!","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"String/FormatPhoneNumber.js","lineNumber":9,"sourceCode":"/**\n * @description - function that takes 10 digits and returns a string of the formatted phone number e.g.: 1234567890 -> (123) 456-7890\n * @param {string} phoneNumber\n * @returns {string} - Format to (XXX) XXX-XXXX pattern\n */\nconst formatPhoneNumber = (phoneNumber) => {\n  if (phoneNumber.length !== 10 || isNaN(phoneNumber)) {\n    // return \"Invalid phone number.\"\n    throw new TypeError('Invalid phone number!')\n  }\n\n  let index = 0\n  return '(XXX) XXX-XXXX'.replace(/X/g, () => phoneNumber[index++])\n}\n\nexport default formatPhoneNumber\n","sourceCodeStart":1,"sourceCodeEnd":17,"githubUrl":"https://github.com/TheAlgorithms/JavaScript/blob/5c39e87a9a31f279c60f830ad74a845e4788a517/String/FormatPhoneNumber.js#L1-L17","documentation":"Guard in formatPhoneNumber: it throws when phoneNumber.length !== 10 OR isNaN(phoneNumber). The function expects a STRING of exactly 10 numeric digits and rebuilds the '(XXX) XXX-XXXX' pattern by indexing into the string. Because it reads .length, a Number has no length (undefined !== 10) and throws; because it uses the coercion-based isNaN, a string of 10 spaces incorrectly passes the numeric check (latent bug). Empty or wrong-length strings throw.","triggerScenarios":"Calling formatPhoneNumber(1234567890) (number, no .length), formatPhoneNumber('123') (too short), formatPhoneNumber('12345678901') (too long), formatPhoneNumber('12345678ab') (non-numeric), formatPhoneNumber('') (length 0), formatPhoneNumber(null) (throws on .length access, possibly a different error).","commonSituations":"Receiving a phone number as a Number from a form/database instead of a string; formatted input with dashes/parens already applied (length > 10); stripped input that retained a country code; whitespace-only input slipping through due to the isNaN coercion bug.","solutions":["Pass a string of exactly 10 digits: strip non-digits first, e.g. String(n).replace(/\\D/g, '').","Validate length === 10 and /^[0-9]{10}$/.test(value) before calling.","Prefer Number.isFinite over the library's isNaN if you fork/patch, to close the whitespace hole."],"exampleFix":"// before\nformatPhoneNumber(rawPhone)\n\n// after\nconst digits = String(rawPhone).replace(/\\D/g, '')\nif (/^[0-9]{10}$/.test(digits)) formatPhoneNumber(digits)","handlingStrategy":"validation","validationCode":"const digits = String(phoneNumber).replace(/\\D/g, '')\nif (!/^[0-9]{10}$/.test(digits)) {\n  throw new TypeError('phoneNumber must be exactly 10 digits')\n}\nformatPhoneNumber(digits)","typeGuard":"const isTenDigitString = (v) => typeof v === 'string' && /^[0-9]{10}$/.test(v)","tryCatchPattern":"try {\n  formatPhoneNumber(raw)\n} catch (e) {\n  if (e instanceof TypeError && /Invalid phone number/i.test(e.message)) {\n    // sanitize and retry, or surface to user\n  } else throw e\n}","preventionTips":["Always strip non-digits first: String(n).replace(/\\D/g, '').","Never pass a Number — it has no .length.","Beware the isNaN coercion hole: validate with a strict regex, not length+isNaN.","Reject formatted input (dashes/parens) before calling."],"tags":["string","validation","phone-number","formatting","coercion-bug"],"backgroundTag":null,"analyzedSha":"5c39e87a9a31f279c60f830ad74a845e4788a517","analyzedAt":"2026-08-13T04:54:54.474Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}