{"record":{"id":"d1969bac88cbc8df","repo":"tiangolo/fastapi","slug":"response-text-d1969b","errorCode":null,"errorMessage":"response.text","messagePattern":"response\\.text","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"scripts/sponsors.py","lineNumber":109,"sourceCode":"\ndef get_graphql_response(\n    *,\n    settings: Settings,\n    query: str,\n    after: str | None = None,\n) -> dict[str, Any]:\n    headers = {\"Authorization\": f\"token {settings.sponsors_token.get_secret_value()}\"}\n    variables = {\"after\": after}\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(f\"Response was not 200, after: {after}\")\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}\")\n        logging.error(data[\"errors\"])\n        logging.error(response.text)\n        raise RuntimeError(response.text)\n    return data\n\n\ndef get_graphql_sponsor_edges(\n    *, settings: Settings, after: str | None = None\n) -> list[SponsorshipAsMaintainerEdge]:\n    data = get_graphql_response(settings=settings, query=sponsors_query, after=after)\n    graphql_response = SponsorsResponse.model_validate(data)\n    return graphql_response.data.user.sponsorshipsAsMaintainer.edges\n\n\ndef get_individual_sponsors(","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/scripts/sponsors.py#L91-L127","documentation":"Raised by get_graphql_response() in scripts/sponsors.py:109 when the GitHub Sponsors GraphQL request returns a non-200 HTTP status. response.text is raised as the message so the API error text is preserved. This is the transport/auth failure path; GraphQL-level errors are handled separately at line 115.","triggerScenarios":"sponsors.main() issues a GraphQL POST to https://api.github.com/graphql authenticated with sponsors_token (scripts/sponsors.py:98). Any status_code != 200 raises here — 401/403 for token/scope issues (the sponsors_token must have access to the user(login: 'tiangolo') sponsorshipsAsMaintainer field), 429 rate limit, 5xx outage.","commonSituations":"SPONSORS_TOKEN expired or revoked. Token is a fine-grained PAT without the sponsors:read scope. Rate limited during a scheduled CI run. GitHub incident.","solutions":["Inspect the logged response.text (scripts/sponsors.py:108 logs it at ERROR) for the exact API message.","Rotate SPONSORS_TOKEN and ensure it can read GitHub Sponsors data for the target user.","For rate limits, back off and retry; for 5xx, retry after a delay.","Confirm httpx_timeout (default 30s) is sufficient for the sponsors query."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import os\n\ndef sponsors_token_present() -> bool:\n    return bool(os.environ.get(\"SPONSORS_TOKEN\"))","typeGuard":null,"tryCatchPattern":"import time, logging\nfor attempt in range(4):\n    try:\n        data = get_graphql_response(settings=settings, query=sponsors_query)\n        break\n    except RuntimeError as e:\n        if attempt == 3:\n            raise\n        logging.warning(f\"Sponsors GraphQL HTTP error, retrying: {e}\")\n        time.sleep(2 ** attempt)","preventionTips":["Use a SPONSORS_TOKEN with the sponsors:read scope for the target maintainer account.","Add exponential backoff for 401/403/429/5xx.","Log response.status_code with response.text for fast triage."],"tags":["network","github","graphql","sponsors","ci"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}