anuraghazra/github-readme-stats · error · Error
${err}
Error message
${err} What it means
Generic Error thrown in totalCommitsFetcher's catch block wrapping whatever the retryer threw: `throw new Error(err)`. Because the retryer can throw CustomError(NO_TOKENS) or CustomError(MAX_RETRY) (and network errors), wrapping them in a fresh Error stringifies the original and discards its .type and .secondaryMessage — a known code smell that loses structured error metadata downstream. The visible message is the stringified underlying error.
Source
Thrown at src/fetchers/stats.js:202
*
* @param {string} username GitHub username.
* @returns {Promise<number>} Total commits.
*
* @description Done like this because the GitHub API does not provide a way to fetch all the commits. See
* #92#issuecomment-661026467 and #211 for more information.
*/
const totalCommitsFetcher = async (username) => {
if (!githubUsernameRegex.test(username)) {
logger.log("Invalid username provided.");
throw new Error("Invalid username provided.");
}
let res;
try {
res = await retryer(fetchTotalCommits, { login: username });
} catch (err) {
logger.log(err);
throw new Error(err);
}
const totalCount = res.data.total_count;
if (!totalCount || isNaN(totalCount)) {
throw new CustomError(
"Could not fetch total commits.",
CustomError.GITHUB_REST_API_ERROR,
);
}
return totalCount;
};
/**
* Fetch stats for a given username.
*
* @param {string} username GitHub username.
* @param {boolean} include_all_commits Include all commits.
* @param {string[]} exclude_repo Repositories to exclude.View on GitHub (pinned to 54a7985aee)
Solutions
- Ensure PAT_1 (and more) are set — NO_TOKENS surfaces here as a stringified CustomError.
- Add tokens to raise the MAX_RETRY ceiling for the REST endpoint.
- If transient, retry the request after the rate-limit window resets.
- If you don't need all-time commits, drop include_all_commits=true to avoid the REST path entirely.
Example fix
// before (config) // include_all_commits=true with no PAT tokens -> 'Error: No GitHub API tokens found' // after // export PAT_1=ghp_xxx (and optionally drop include_all_commits)
Defensive patterns
Strategy: try-catch
Validate before calling
// The wrapped error is opaque; pre-validate token presence to avoid NO_TOKENS reaching here.
function assertTokensForRestPath() {
const has = Object.keys(process.env).some((k) => /PAT_\d*$/.test(k));
if (!has && process.env.NODE_ENV !== "test") {
throw new Error("include_all_commits requires at least one PAT_N token");
}
} Try / catch
// The original CustomError type is lost in the wrap; match on substrings as a workaround.
try {
stats.totalCommits = await totalCommitsFetcher(username);
} catch (err) {
if (/No GitHub API tokens found/.test(err.message)) handleMissingTokens();
else if (/rate limiting/.test(err.message)) handleRateLimit();
else throw err;
} Prevention
- Note this error wraps and stringifies the underlying CustomError, losing .type — match on message text if you must branch.
- Set PAT tokens and limit include_all_commits usage to reduce exposure to the REST search path.
When it happens
Trigger: include_all_commits=true and the retryer (driving fetchTotalCommits against the REST /search/commits endpoint) throws: all tokens rate-limited (MAX_RETRY), no tokens configured (NO_TOKENS), or a network/axios failure that the retryer re-throws when e.response is absent.
Common situations: Self-hosted instance with no/insufficient tokens hitting the all-commits path; a rate-limit storm against the REST search endpoint; or a network blip between the instance and api.github.com. The original error type is invisible because of the wrap.
Related errors
- Invalid username provided.
- GITHUB_REST_API_ERROR
- MAX_RETRY
- Missing params "username" make sure you pass the parameters
- USER_NOT_FOUND
AI-assisted analysis of anuraghazra/github-readme-stats@54a7985aee (2026-08-12).
Data as JSON: /api/errors/7b54a6291a3027bd.
Report an issue: GitHub.