fastapi/fastapi · error · RuntimeError

response.text

Error message

response.text

What it means

Failure in scripts/notify_translations.py get_graphql_response (:226-230): the script POSTs a GraphQL query to GitHub's API (github_graphql_url) with a token; when the HTTP status is anything other than 200 (401 bad token, 403 rate limit/forbidden, 5xx), it logs the response and raises RuntimeError(response.text). This is CI automation (translation notification bot), not library runtime code; the raised message is the raw GitHub error body.

Source

Thrown at scripts/notify_translations.py:229

        "after": after,
        "category_id": category_id,
        "discussion_number": discussion_number,
        "discussion_id": discussion_id,
        "comment_id": comment_id,
        "body": body,
    }
    response = httpx.post(
        github_graphql_url,
        headers=headers,
        timeout=settings.httpx_timeout,
        json={"query": query, "variables": variables, "operationName": "Q"},
    )
    if response.status_code != 200:
        logging.error(
            f"Response was not 200, after: {after}, category_id: {category_id}"
        )
        logging.error(response.text)
        raise RuntimeError(response.text)
    data = response.json()
    if "errors" in data:
        logging.error(f"Errors in response, after: {after}, category_id: {category_id}")
        logging.error(data["errors"])
        logging.error(response.text)
        raise RuntimeError(response.text)
    return cast(dict[str, Any], data)


def get_graphql_translation_discussions(
    *, settings: Settings
) -> list[AllDiscussionsDiscussionNode]:
    data = get_graphql_response(
        settings=settings,
        query=all_discussions_query,
        category_id=questions_translations_category_id,
    )
    graphql_response = AllDiscussionsResponse.model_validate(data)

View on GitHub (pinned to a1fa70d423)

Solutions

  1. Read the logged response body first — it states the exact cause (invalid token, rate limit, blocked).
  2. For 401: refresh/fix the token (GITHUB_TOKEN secret) and confirm it has access to the repo's discussions.
  3. For rate limits: wait for the window to reset (check RateLimit headers) or reduce how often the workflow runs; authenticated GraphQL quota is per-hour.
  4. For transient 5xx: re-run the failed CI job (retry).

Example fix

# before (CI env)
GITHUB_TOKEN=expired-token  # -> RuntimeError(response.text): Bad credentials

# after: supply a fresh, sufficiently scoped token
GITHUB_TOKEN=<valid token with repo/discussions read scope>
Defensive patterns

Strategy: retry

Validate before calling

def graphql_ok(token: str) -> bool:
    r = httpx.post(
        "https://api.github.com/graphql",
        headers={"Authorization": f"bearer {token}"},
        json={"query": "{ viewer { login } }"},
        timeout=30,
    )
    return r.status_code == 200

Try / catch

for attempt in range(3):
    response = httpx.post(url, headers=headers, json=payload, timeout=30)
    if response.status_code == 200:
        break
    if response.status_code in (401,):  # not retryable
        raise RuntimeError(response.text)
    time.sleep(2 ** attempt)
else:
    raise RuntimeError(response.text)

Prevention

When it happens

Trigger: Running notify_translations in CI with an expired/invalid GITHUB_TOKEN (401), hitting the GraphQL rate limit or secondary rate limiting (403/429 with 'API rate limit exceeded' in the body), or GitHub returning 502/5xx. Any non-200 status triggers the raise.

Common situations: GitHub Actions token permissions changed or token expired; a busy repo consuming the GraphQL quota; intermittent GitHub outages; incorrect GITHUB_GRAPHQL_URL env override pointing at a bad endpoint.

Related errors


AI-assisted analysis of fastapi/fastapi@a1fa70d423 (2026-08-14). Data as JSON: /api/errors/2577b0fa63ee45c8. Report an issue: GitHub.