anuraghazra/github-readme-stats · error · CustomError

res.statusText

res.statusText

Error message

${res.data.errors[0].message}

What it means

The non-NOT_FOUND, message-bearing GraphQL error branch. It fires when res.data.errors[0].message is truthy but the error's type is not "NOT_FOUND". Critically, the error code passed to CustomError is res.statusText, not a stable constant: for a GraphQL response delivered over HTTP 200 that string is literally "OK", and for an HTTP error response surfaced by the retryer (which returns e.response) it is the HTTP phrase such as "Forbidden". Because res.statusText is almost never a key in SECONDARY_ERROR_MESSAGES, the secondaryMessage degrades to the statusText itself, so callers cannot reliably switch on the code.

Source

Thrown at src/fetchers/top-languages.js:83

  size_weight = 1,
  count_weight = 0,
) => {
  if (!username) {
    throw new MissingParamError(["username"]);
  }

  const res = await retryer(fetcher, { login: username });

  if (res.data.errors) {
    logger.error(res.data.errors);
    if (res.data.errors[0].type === "NOT_FOUND") {
      throw new CustomError(
        res.data.errors[0].message || "Could not fetch user.",
        CustomError.USER_NOT_FOUND,
      );
    }
    if (res.data.errors[0].message) {
      throw new CustomError(
        wrapTextMultiline(res.data.errors[0].message, 90, 1)[0],
        res.statusText,
      );
    }
    throw new CustomError(
      "Something went wrong while trying to retrieve the language data using the GraphQL API.",
      CustomError.GRAPHQL_ERROR,
    );
  }

  let repoNodes = res.data.data.user.repositories.nodes;
  /** @type {Record<string, boolean>} */
  let repoToHide = {};
  const allExcludedRepos = [...exclude_repo, ...excludeRepositories];

  // populate repoToHide map for quick lookup
  // while filtering out
  if (allExcludedRepos) {

View on GitHub (pinned to 54a7985aee)

Solutions

  1. Check https://www.githubstatus.com for an active GitHub API incident and retry after it resolves.
  2. Inspect the server logs: logger.error(res.data.errors) prints the raw GraphQL error just before this throw; read its message to find the real cause.
  3. Verify the PAT_1 token used by the retryer has the expected scopes and is not revoked.
  4. Retry with exponential backoff; if the message indicates a permanent schema problem, update the GraphQL query string in the fetcher to match the current GitHub schema.
Defensive patterns

Strategy: retry

Validate before calling

// You cannot validate an upstream GraphQL error away, but you can cap concurrency
// and ensure a valid token is configured to reduce transient failures.
function assertTokenConfigured() {
  if (!process.env.PAT_1) {
    throw new Error("PAT_1 env var is not set; GitHub GraphQL will reject requests");
  }
}
assertTokenConfigured();

Type guard

// This error's `type` is res.statusText (e.g. "OK"/"Forbidden"), so guard by message shape
function isUpstreamGraphqlError(err) {
  return err instanceof CustomError && typeof err.message === "string";
}

Try / catch

async function fetchWithRetry(username, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try {
      return await fetchTopLanguages(username);
    } catch (err) {
      const transient = err instanceof CustomError &&
        ![CustomError.USER_NOT_FOUND, CustomError.NO_TOKENS].includes(err.type);
      if (!transient || i === attempts - 1) throw err;
      await new Promise((r) => setTimeout(r, 2 ** i * 500)); // backoff
    }
  }
}

Prevention

When it happens

Trigger: GitHub's GraphQL endpoint returns HTTP 200 with a body-level errors array carrying a message but a type other than NOT_FOUND (and other than RATE_LIMITED, which the retryer already retries). Examples: GitHub service instability returning "Something went wrong while executing your query.", secondary-rate-limit messages whose type is not RATE_LIMITED, or schema/field errors after an API change. Less commonly, the retryer returns a non-2xx e.response and the body still parses into res.data.errors with a message.

Common situations: A live GitHub API incident (check githubstatus.com); a PAT whose scopes trigger a GraphQL-level error with a message; an upstream schema change that breaks the hardcoded query in src/fetchers/top-languages.js:20; transient partial failures during high traffic.

Related errors


AI-assisted analysis of anuraghazra/github-readme-stats@54a7985aee (2026-08-12). Data as JSON: /api/errors/d5e36cf3b597487c. Report an issue: GitHub.