{"record":{"id":"44d0bf635d79dfdf","repo":"TheAlgorithms/JavaScript","slug":"input-data-must-be-strings","errorCode":null,"errorMessage":"Input data must be strings","messagePattern":"Input data must be strings","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"String/PercentageOfLetters.js","lineNumber":15,"sourceCode":"/**\n * @function percentageOfLetter\n * @description Return the percentage of characters in 'str'\n * that equal 'letter' rounded down to the nearest whole percent.\n * More info: https://leetcode.com/problems/percentage-of-letter-in-string/\n * @param {String} str\n * @param {String} letter\n * @returns {Number}\n * @example\n * const str = 'foobar', const letter = 'o'\n * percentageOfLetter(str, letter) // ===> 33\n */\nconst percentageOfLetter = (str, letter) => {\n  if (typeof str !== 'string' || typeof letter !== 'string') {\n    throw new Error('Input data must be strings')\n  }\n  let letterCount = 0\n  // Iterate through the whole given text\n  for (let i = 0; i < str.length; i++) {\n    // Count how often the letter appears in the word\n    letterCount += str[i].toLowerCase() === letter.toLowerCase() ? 1 : 0\n  }\n  const percentage = Math.floor((100 * letterCount) / str.length)\n  return percentage\n}\n\nexport { percentageOfLetter }\n","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/TheAlgorithms/JavaScript/blob/5c39e87a9a31f279c60f830ad74a845e4788a517/String/PercentageOfLetters.js#L1-L28","documentation":"Guard in percentageOfLetter. The function computes the floor percentage of characters in str equal to letter and requires BOTH arguments to be strings, throwing a plain Error (not TypeError) otherwise. Note there is NO empty-string guard: an empty str yields division 100*0/0 = NaN, and a multi-character letter is compared only by its first character implicitly via iteration.","triggerScenarios":"Calling percentageOfLetter(null, 'o'), percentageOfLetter('foo', undefined), percentageOfLetter(42, '4'), percentageOfLetter('foo', ['o']). Either argument non-string.","commonSituations":"An optional letter parameter omitted; str read from a source returning null; a number passed where a string was expected; empty str passed (does not throw but returns NaN).","solutions":["Ensure both arguments are strings; default missing values sensibly.","Guard for empty str before calling to avoid the NaN result.","Validate letter.length === 1 if a single character is expected."],"exampleFix":"// before\npercentageOfLetter(str, letter)\n\n// after\nif (typeof str === 'string' && typeof letter === 'string' && str.length) {\n  percentageOfLetter(str, letter)\n}","handlingStrategy":"type-guard","validationCode":"if (typeof str !== 'string' || typeof letter !== 'string') {\n  throw new Error('str and letter must be strings')\n}\nif (str.length === 0) throw new Error('str must be non-empty')\npercentageOfLetter(str, letter)","typeGuard":"const areStrings = (a, b) => typeof a === 'string' && typeof b === 'string'","tryCatchPattern":"try {\n  percentageOfLetter(str, letter)\n} catch (e) {\n  if (e instanceof Error && /must be strings/i.test(e.message)) { /* coerce and retry */ } else throw e\n}","preventionTips":["Also guard for empty str to avoid the NaN return value.","Validate letter.length === 1 if a single char is expected.","Note this throws Error, not TypeError — instanceof checks differ."],"tags":["string","validation","type-guard","percentage","nan-risk"],"backgroundTag":null,"analyzedSha":"5c39e87a9a31f279c60f830ad74a845e4788a517","analyzedAt":"2026-08-13T04:54:54.474Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}