{"record":{"id":"a9fab4eab99bf2d1","repo":"TheAlgorithms/JavaScript","slug":"input-must-be-a-string-or-a-number","errorCode":null,"errorMessage":"Input must be a string or a number","messagePattern":"Input must be a string or a number","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"String/IsPalindrome.js","lineNumber":21,"sourceCode":" * @description isPalindromeIterative function checks whether the provided input is palindrome or not\n * @param {String | Number} x - The input to check\n * @return {boolean} - Input is palindrome or not\n * @see [Palindrome](https://en.wikipedia.org/wiki/Palindrome)\n */\n\n/*\n  * Big-O Analysis\n      * Time Complexity\n        - O(N) on average and worst case scenario as input is traversed in linear fashion\n        - O(1) on best case scenario if the input already is a string (otherwise toString() method takes O(N))\n               and the first & last characters don't match, triggering an early return\n      * Space Complexity\n        - O(1)\n*/\n\nexport function isPalindromeIterative(x) {\n  if (typeof x !== 'string' && typeof x !== 'number') {\n    throw new TypeError('Input must be a string or a number')\n  }\n\n  // Convert x to string whether it's number or string\n  const string = x.toString()\n  const length = string.length\n\n  if (length === 1) return true\n\n  // Apply two pointers technique to compare first and last elements on each iteration\n  for (let start = 0, end = length - 1; start < end; start++, end--) {\n    // Early return if compared items are different, input is not a palindrome\n    if (string[start] !== string[end]) return false\n  }\n  // If early return in condition inside for loop is not reached, then input is palindrome\n  return true\n}\n","sourceCodeStart":3,"sourceCodeEnd":38,"githubUrl":"https://github.com/TheAlgorithms/JavaScript/blob/5c39e87a9a31f279c60f830ad74a845e4788a517/String/IsPalindrome.js#L3-L38","documentation":"Guard in isPalindromeIterative. Unlike the other string utilities, this one accepts EITHER a string OR a number (it calls .toString() internally). It throws TypeError only for inputs that are neither — booleans, objects, arrays, null, undefined, functions, symbols all throw.","triggerScenarios":"Calling isPalindromeIterative(null), isPalindromeIterative(undefined), isPalindromeIterative(true), isPalindromeIterative({}), isPalindromeIterative([1,2,1]), isPalindromeIterative(Symbol()).","commonSituations":"A value read from a loosely-typed source (form, JSON) where the type is unknown; passing an array of digits thinking it will be compared element-wise; a boolean flag accidentally forwarded.","solutions":["Pass a string or number; coerce first with String(value) for safety.","Pre-validate: typeof x === 'string' || typeof x === 'number'.","Reject objects/arrays explicitly before the call."],"exampleFix":"// before\nisPalindromeIterative(maybeValue)\n\n// after\nconst t = typeof maybeValue\nif (t === 'string' || t === 'number') isPalindromeIterative(maybeValue)\nelse throw new TypeError('expected string or number, got ' + t)","handlingStrategy":"type-guard","validationCode":"if (typeof x !== 'string' && typeof x !== 'number') {\n  throw new TypeError('x must be a string or number')\n}\nisPalindromeIterative(x)","typeGuard":"const isStringOrNumber = (v) => typeof v === 'string' || typeof v === 'number'","tryCatchPattern":"try {\n  isPalindromeIterative(x)\n} catch (e) {\n  if (e instanceof TypeError) { /* not string/number */ } else throw e\n}","preventionTips":["Coerce unknown values with String() before passing.","Reject arrays/objects explicitly — they are not auto-joined.","Remember booleans, null, undefined all throw."],"tags":["string","validation","type-guard","palindrome","number"],"backgroundTag":null,"analyzedSha":"5c39e87a9a31f279c60f830ad74a845e4788a517","analyzedAt":"2026-08-13T04:54:54.474Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}