{"record":{"id":"cd90e90ee74cdbbb","repo":"TheAlgorithms/JavaScript","slug":"input-should-be-a-string","errorCode":null,"errorMessage":"Input should be a string","messagePattern":"Input should be a string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"String/CountLetters.js","lineNumber":13,"sourceCode":"/**\n * @function countLetters\n * @description Given a string, count the number of each letter.\n * @param {String} str - The input string\n * @return {Object} - Object with letters and number of times\n * @example countLetters(\"hello\") => {h: 1, e: 1, l: 2, o: 1}\n */\n\nconst countLetters = (str) => {\n  const specialChars = /\\W/g\n\n  if (typeof str !== 'string') {\n    throw new TypeError('Input should be a string')\n  }\n\n  if (specialChars.test(str)) {\n    throw new TypeError('Input must not contain special characters')\n  }\n\n  if (/\\d/.test(str)) {\n    throw new TypeError('Input must not contain numbers')\n  }\n\n  const obj = {}\n  for (let i = 0; i < str.toLowerCase().length; i++) {\n    const char = str.toLowerCase().charAt(i)\n    obj[char] = (obj[char] || 0) + 1\n  }\n\n  return obj\n}","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/TheAlgorithms/JavaScript/blob/5c39e87a9a31f279c60f830ad74a845e4788a517/String/CountLetters.js#L1-L31","documentation":"First guard in countLetters. The function counts each letter in a string and rejects non-string input with TypeError before any further processing. This is the outermost of three stacked guards (type, then special characters, then digits).","triggerScenarios":"Calling countLetters(undefined), countLetters(null), countLetters(42), countLetters(['a','b']). Any input where typeof !== 'string'.","commonSituations":"A function that previously received a string now receives a parsed JSON object; user input that was Number()-coerced earlier; an array passed where a flattened string was intended.","solutions":["Pass a string; if the source is missing, default to '' (note '' returns {}).","Validate typeof at the call site.","If the source is an array of chars, join first."],"exampleFix":"// before\ncountLetters(input)\n\n// after\ncountLetters(typeof input === 'string' ? input : '')","handlingStrategy":"type-guard","validationCode":"if (typeof str !== 'string') {\n  throw new TypeError('str must be a string')\n}\ncountLetters(str)","typeGuard":"const isString = (v) => typeof v === 'string'","tryCatchPattern":"try {\n  countLetters(input)\n} catch (e) {\n  if (e instanceof TypeError && /should be a string/i.test(e.message)) { /* handle */ } else throw e\n}","preventionTips":["Default to '' when the source is optional.","Validate typeof at the boundary.","Document that countLetters is letters-only to prevent the next two errors."],"tags":["string","validation","type-guard","letter-count"],"backgroundTag":null,"analyzedSha":"5c39e87a9a31f279c60f830ad74a845e4788a517","analyzedAt":"2026-08-13T04:54:54.474Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}