{"record":{"id":"06a1b6ff426499d7","repo":"anuraghazra/github-readme-stats","slug":"missing-params-username-make-sure-you-pass-the-p-06a1b6","errorCode":null,"errorMessage":"Missing params \"username\" make sure you pass the parameters in URL","messagePattern":"Missing params \"username\" make sure you pass the parameters in URL","errorType":"validation","errorClass":"MissingParamError","httpStatus":null,"severity":"warning","filePath":"src/fetchers/top-languages.js","lineNumber":69,"sourceCode":" */\n\n/**\n * Fetch top languages for a given username.\n *\n * @param {string} username GitHub username.\n * @param {string[]} exclude_repo List of repositories to exclude.\n * @param {number} size_weight Weightage to be given to size.\n * @param {number} count_weight Weightage to be given to count.\n * @returns {Promise<TopLangData>} Top languages data.\n */\nconst fetchTopLanguages = async (\n  username,\n  exclude_repo = [],\n  size_weight = 1,\n  count_weight = 0,\n) => {\n  if (!username) {\n    throw new MissingParamError([\"username\"]);\n  }\n\n  const res = await retryer(fetcher, { login: username });\n\n  if (res.data.errors) {\n    logger.error(res.data.errors);\n    if (res.data.errors[0].type === \"NOT_FOUND\") {\n      throw new CustomError(\n        res.data.errors[0].message || \"Could not fetch user.\",\n        CustomError.USER_NOT_FOUND,\n      );\n    }\n    if (res.data.errors[0].message) {\n      throw new CustomError(\n        wrapTextMultiline(res.data.errors[0].message, 90, 1)[0],\n        res.statusText,\n      );\n    }","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/anuraghazra/github-readme-stats/blob/54a7985aeefda00d5eadb55b80c17c7f976c37d2/src/fetchers/top-languages.js#L51-L87","documentation":"Thrown by fetchTopLanguages when its first positional argument, username, is falsy (undefined, null, or empty string). It is raised before any network call, so it signals a contract violation by the caller, not a GitHub API problem. The message is generated by the generic MissingParamError class (src/common/error.js:49), which formats the missedParams array into the fixed string. Because the check is `if (!username)`, even whitespace-only or the string \"0\" edge cases aside, any absent/blank username trips it.","triggerScenarios":"Calling fetchTopLanguages(undefined, ...) or fetchTopLanguages(\"\", ...) directly. Via the HTTP API (api/top-langs.js:121), this happens on a GET /api/top-langs request whose query string omits ?username= entirely, or supplies ?username= with an empty value (req.query.username is then undefined or \"\").","commonSituations":"A README card image URL where the ?username= query parameter was forgotten or auto-stripped by a markdown renderer; programmatic callers that destructure username from a config object that does not contain the key; copy-paste of the badge URL without filling in the template placeholder.","solutions":["Ensure the request URL includes a non-empty ?username=<github-login> query parameter, e.g. /api/top-langs?username=octocat.","If calling fetchTopLanguages directly, pass a validated non-empty string as the first argument before invoking it.","At the caller/API layer, short-circuit with your own error response when req.query.username is missing so the user gets a clearer message than the fetcher's generic one."],"exampleFix":"// before\nconst topLangs = await fetchTopLanguages(req.query.username);\n\n// after\nconst username = req.query.username;\nif (!username || !username.trim()) {\n  return res.status(400).send(\"username query parameter is required\");\n}\nconst topLangs = await fetchTopLanguages(username.trim());","handlingStrategy":"validation","validationCode":"// Run before calling fetchTopLanguages\nfunction requireUsername(username) {\n  if (typeof username !== \"string\" || username.trim() === \"\") {\n    throw new Error(\"'username' must be a non-empty string\");\n  }\n  return username.trim();\n}\n\n// usage\nconst username = requireUsername(req.query.username);\nconst topLangs = await fetchTopLanguages(username, excludeRepo);","typeGuard":"/** @param {unknown} v */\nfunction isNonEmptyString(v) {\n  return typeof v === \"string\" && v.trim().length > 0;\n}\n\nif (!isNonEmptyString(username)) {\n  return res.status(400).send(\"username query parameter is required\");\n}","tryCatchPattern":"try {\n  const topLangs = await fetchTopLanguages(username);\n} catch (err) {\n  if (err instanceof MissingParamError && err.missedParams.includes(\"username\")) {\n    // caller-side bad request: surface a 400, do not retry\n    return res.status(400).send(err.message);\n  }\n  throw err;\n}","preventionTips":["Always validate query params at the API boundary before forwarding to a fetcher.","Treat the username field as required in any URL template and lint that it is substituted.","Unit-test the param-missing case so the 400 path is covered."],"tags":["validation","params","user-input","github-api"],"backgroundTag":null,"analyzedSha":"54a7985aeefda00d5eadb55b80c17c7f976c37d2","analyzedAt":"2026-08-12T23:20:41.776Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}