{"record":{"id":"2577b0fa63ee45c8","repo":"fastapi/fastapi","slug":"response-text","errorCode":null,"errorMessage":"response.text","messagePattern":"response\\.text","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"scripts/notify_translations.py","lineNumber":229,"sourceCode":"        \"after\": after,\n        \"category_id\": category_id,\n        \"discussion_number\": discussion_number,\n        \"discussion_id\": discussion_id,\n        \"comment_id\": comment_id,\n        \"body\": body,\n    }\n    response = httpx.post(\n        github_graphql_url,\n        headers=headers,\n        timeout=settings.httpx_timeout,\n        json={\"query\": query, \"variables\": variables, \"operationName\": \"Q\"},\n    )\n    if response.status_code != 200:\n        logging.error(\n            f\"Response was not 200, after: {after}, category_id: {category_id}\"\n        )\n        logging.error(response.text)\n        raise RuntimeError(response.text)\n    data = response.json()\n    if \"errors\" in data:\n        logging.error(f\"Errors in response, after: {after}, category_id: {category_id}\")\n        logging.error(data[\"errors\"])\n        logging.error(response.text)\n        raise RuntimeError(response.text)\n    return cast(dict[str, Any], data)\n\n\ndef get_graphql_translation_discussions(\n    *, settings: Settings\n) -> list[AllDiscussionsDiscussionNode]:\n    data = get_graphql_response(\n        settings=settings,\n        query=all_discussions_query,\n        category_id=questions_translations_category_id,\n    )\n    graphql_response = AllDiscussionsResponse.model_validate(data)","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/fastapi/fastapi/blob/a1fa70d4237d50aae6586a0d9b229df583463d21/scripts/notify_translations.py#L211-L247","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the logged response body first — it states the exact cause (invalid token, rate limit, blocked).","For 401: refresh/fix the token (GITHUB_TOKEN secret) and confirm it has access to the repo's discussions.","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.","For transient 5xx: re-run the failed CI job (retry)."],"exampleFix":"# before (CI env)\nGITHUB_TOKEN=expired-token  # -> RuntimeError(response.text): Bad credentials\n\n# after: supply a fresh, sufficiently scoped token\nGITHUB_TOKEN=<valid token with repo/discussions read scope>","handlingStrategy":"retry","validationCode":"def graphql_ok(token: str) -> bool:\n    r = httpx.post(\n        \"https://api.github.com/graphql\",\n        headers={\"Authorization\": f\"bearer {token}\"},\n        json={\"query\": \"{ viewer { login } }\"},\n        timeout=30,\n    )\n    return r.status_code == 200","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    response = httpx.post(url, headers=headers, json=payload, timeout=30)\n    if response.status_code == 200:\n        break\n    if response.status_code in (401,):  # not retryable\n        raise RuntimeError(response.text)\n    time.sleep(2 ** attempt)\nelse:\n    raise RuntimeError(response.text)","preventionTips":["Rotate tokens before expiry and grant the minimum scopes the script needs (repo discussions read).","Check rate-limit headers and back off near the quota instead of failing the run.","Classify statuses: retry 5xx/429 with backoff, fail fast on 401/403."],"tags":["fastapi","ci","github-api","graphql","auth","network"],"backgroundTag":null,"analyzedSha":"a1fa70d4237d50aae6586a0d9b229df583463d21","analyzedAt":"2026-08-14T19:41:58.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}