{"record":{"id":"25d7c9dd20b343a5","repo":"anuraghazra/github-readme-stats","slug":"res-statustext","errorCode":"res.statusText","errorMessage":"${res.data.errors[0].message}","messagePattern":"\\$\\{res\\.data\\.errors\\[0\\]\\.message\\}","errorType":"error_code","errorClass":"CustomError","httpStatus":null,"severity":"error","filePath":"src/fetchers/stats.js","lineNumber":273,"sourceCode":"  let res = await statsFetcher({\n    username,\n    includeMergedPullRequests: include_merged_pull_requests,\n    includeDiscussions: include_discussions,\n    includeDiscussionsAnswers: include_discussions_answers,\n    startTime: commits_year ? `${commits_year}-01-01T00:00:00Z` : undefined,\n  });\n\n  // Catch GraphQL errors.\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    }\n    throw new CustomError(\n      \"Something went wrong while trying to retrieve the stats data using the GraphQL API.\",\n      CustomError.GRAPHQL_ERROR,\n    );\n  }\n\n  const user = res.data.data.user;\n\n  stats.name = user.name || user.login;\n\n  // if include_all_commits, fetch all commits using the REST API.\n  if (include_all_commits) {\n    stats.totalCommits = await totalCommitsFetcher(username);\n  } else {","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/anuraghazra/github-readme-stats/blob/54a7985aeefda00d5eadb55b80c17c7f976c37d2/src/fetchers/stats.js#L255-L291","documentation":"CustomError thrown by fetchStats when the GraphQL response has errors but the first error's type is not NOT_FOUND and it has a message. The thrown message is the first error message wrapped via wrapTextMultiline(...,90,1)[0] (line-wrapped to 90 cols), and notably the error's .type is set to res.statusText — the HTTP status text (e.g. 'OK', 'Forbidden') — not a stable CustomError constant. The secondaryMessage then becomes statusText too (via the SECONDARY_ERROR_MESSAGES fallback), so this is essentially a generic passthrough of any non-NOT_FOUND GraphQL error.","triggerScenarios":"GitHub returns a GraphQL errors array with a message but a type other than NOT_FOUND — e.g. FORBIDDEN (token lacks scope), RATE_LIMITED that survived the retryer, or a query validation error. Because the retryer only auto-recurses on RATE_LIMITED, other rate-limit-adjacent or permission errors reach this branch.","commonSituations":"A token missing the scopes needed for the stats query; a deprecated GraphQL field after an API change; or a non-NOT_FOUND server-side error from GitHub. Using res.statusText as the type is a smell — the 'code' is not a stable identifier.","solutions":["Inspect the raw GraphQL error message (it is the thrown message) for the real cause.","If permission-related, regenerate PAT_1 with read:user and public_repo scopes.","Retry for transient GitHub-side GraphQL errors.","If a field was deprecated, update the project or pin a compatible version."],"exampleFix":"// before: token missing scopes\n// PAT_1 has no read:user scope -> GraphQL FORBIDDEN, message surfaced here\n\n// after: regenerate token with read:user + public_repo scopes","handlingStrategy":"try-catch","validationCode":"// Loose pre-check that the token can read user data (reduces FORBIDDEN reaching this branch).\nasync function tokenCanReadUsers(token) {\n  const r = await fetch(\"https://api.github.com/user\", {\n    headers: { Authorization: `token ${token}` },\n  });\n  return r.ok;\n}","typeGuard":null,"tryCatchPattern":"// err.type here is res.statusText (e.g. 'Forbidden'), not a stable constant — log the message.\ntry {\n  return await fetchStats(username);\n} catch (err) {\n  console.warn(\"stats GraphQL error:\", err.message, \"type/statusText:\", err.type);\n  throw err;\n}","preventionTips":["Don't switch on err.type for this error — it is res.statusText, not a CustomError constant. Switch on message content instead.","Keep PAT_1 scopes at read:user + public_repo to avoid permission-driven GraphQL errors."],"tags":["stats","graphql","github-api","permissions","error-passthrough"],"backgroundTag":null,"analyzedSha":"54a7985aeefda00d5eadb55b80c17c7f976c37d2","analyzedAt":"2026-08-12T23:20:41.776Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}