{"record":{"id":"acdb9f988d6f698f","repo":"anuraghazra/github-readme-stats","slug":"missing-params-username-make-sure-you-pass-the-p","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":"error","filePath":"src/fetchers/repo.js","lineNumber":74,"sourceCode":"const urlExample = \"/api/pin?username=USERNAME&amp;repo=REPO_NAME\";\n\n/**\n * @typedef {import(\"./types\").RepositoryData} RepositoryData Repository data.\n */\n\n/**\n * Fetch repository data.\n *\n * @param {string} username GitHub username.\n * @param {string} reponame GitHub repository name.\n * @returns {Promise<RepositoryData>} Repository data.\n */\nconst fetchRepo = async (username, reponame) => {\n  if (!username && !reponame) {\n    throw new MissingParamError([\"username\", \"repo\"], urlExample);\n  }\n  if (!username) {\n    throw new MissingParamError([\"username\"], urlExample);\n  }\n  if (!reponame) {\n    throw new MissingParamError([\"repo\"], urlExample);\n  }\n\n  let res = await retryer(fetcher, { login: username, repo: reponame });\n\n  const data = res.data.data;\n\n  if (!data.user && !data.organization) {\n    throw new Error(\"Not found\");\n  }\n\n  const isUser = data.organization === null && data.user;\n  const isOrg = data.user === null && data.organization;\n\n  if (isUser) {\n    if (!data.user.repository || data.user.repository.isPrivate) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/anuraghazra/github-readme-stats/blob/54a7985aeefda00d5eadb55b80c17c7f976c37d2/src/fetchers/repo.js#L56-L92","documentation":"MissingParamError thrown by fetchRepo when reponame is present (truthy) but username is falsy. The constructor reports only \"username\" as missing and reuses urlExample as the secondary message. The order of the three guards means this branch is only reached when (!username && !reponame) was false, i.e. repo was supplied.","triggerScenarios":"A request like /api/pin?repo=github-readme-stats with no username. The combined-missing guard at line 70 is skipped (reponame is truthy), so execution falls to the username-only check at line 73.","commonSituations":"A URL template that interpolates the repo name but leaves the owner blank; copy-paste that dropped the username= segment; or a generator that has the repo but not the owner.","solutions":["Add the owner: /api/pin?username=<owner>&repo=<name>.","Validate that username is non-empty before constructing the request URL."],"exampleFix":"// before\n// GET /api/pin?repo=github-readme-stats\n\n// after\n// GET /api/pin?username=anuraghazra&repo=github-readme-stats","handlingStrategy":"validation","validationCode":"function requireUsername(username) {\n  if (!username || typeof username !== \"string\") {\n    throw new Error(\"username is required: /api/pin?username=OWNER&repo=NAME\");\n  }\n}","typeGuard":"const isNonEmptyString = (v) => typeof v === \"string\" && v.trim().length > 0;","tryCatchPattern":null,"preventionTips":["Coerce and trim req.query.username at the handler; reject empty before calling fetchRepo.","Build URLs from a typed object so a missing owner is a compile-time-visible gap."],"tags":["repo-card","missing-param","validation","query-params"],"backgroundTag":null,"analyzedSha":"54a7985aeefda00d5eadb55b80c17c7f976c37d2","analyzedAt":"2026-08-12T23:20:41.776Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}