{"record":{"id":"7bc74587322a3373","repo":"666ghj/MiroFish","slug":"github-api-returned-invalid-response-metadata","errorCode":null,"errorMessage":"GitHub API returned invalid response metadata","messagePattern":"GitHub API returned invalid response metadata","errorType":"exception","errorClass":"FetchError","httpStatus":null,"severity":"error","filePath":"scripts/fetch_star_count.py","lineNumber":62,"sourceCode":"        return FetchError(\"GitHub API authentication failed\")\n    if status == 403:\n        return FetchError(\"GitHub API request was denied\")\n    if status == 404:\n        return FetchError(\"repository metadata was not found\")\n    if status == 429:\n        return FetchError(\"GitHub API rate limit was exhausted\")\n    if 500 <= status <= 599:\n        return FetchError(\"GitHub API is unavailable\")\n    return FetchError(\"GitHub API request failed\")\n\n\ndef _read_response(response: Any) -> bytes:\n    raw_length = response.headers.get(\"Content-Length\")\n    if raw_length is not None:\n        try:\n            content_length = int(raw_length, 10)\n        except (TypeError, ValueError) as exc:\n            raise FetchError(\"GitHub API returned invalid response metadata\") from exc\n        if content_length < 0 or content_length > MAX_HTTP_BYTES:\n            raise FetchError(\"GitHub API response exceeded the size limit\")\n\n    payload = response.read(MAX_HTTP_BYTES + 1)\n    if len(payload) > MAX_HTTP_BYTES:\n        raise FetchError(\"GitHub API response exceeded the size limit\")\n    return payload\n\n\ndef fetch_star_count(token: str, opener: Any | None = None) -> int:\n    if not token or len(token) > 4_096 or \"\\r\" in token or \"\\n\" in token:\n        raise FetchError(\"GITHUB_TOKEN is missing or invalid\")\n\n    request = urllib.request.Request(\n        API_URL,\n        headers={\n            \"Accept\": \"application/vnd.github+json\",\n            \"Authorization\": f\"Bearer {token}\",","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/scripts/fetch_star_count.py#L44-L80","documentation":"Raised by _read_response in scripts/fetch_star_count.py when the HTTP response's Content-Length header exists but cannot be parsed as a base-10 integer (int() raises TypeError or ValueError). This is a defense-in-depth check on response metadata before any body bytes are trusted; a non-numeric Content-Length means the response is malformed or something is intercepting the connection.","triggerScenarios":"GitHub (or a man-in-the-middle proxy) returns a Content-Length like 'abc', '', '12 34', or a hex value; a corporate proxy rewrites headers inconsistently; a mocked test opener returns a headers mapping whose value is not a clean digit string.","commonSituations":"Corporate transparent proxies or antivirus SSL inspection mangling headers; misconfigured local mock/test doubles that set Content-Length to arbitrary objects; exotic CDN edge behavior during incidents.","solutions":["Retry the fetch once: transient proxy/edge malformation usually does not repeat.","If behind a corporate proxy or SSL-inspecting appliance, bypass it for api.github.com or export HTTPS_PROXY correctly.","If this reproduces deterministically, capture response.headers (never the token) and check what is actually returning the malformed header — it is almost never api.github.com itself.","In tests, make the fake response's headers return plain digit strings (e.g. {'Content-Length': '123'})."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from scripts.fetch_star_count import FetchError, fetch_star_count\n\ntry:\n    count = fetch_star_count(token)\nexcept FetchError as exc:\n    if exc.args[0] == \"GitHub API returned invalid response metadata\":\n        # header-level malformation: do not retry blindly, inspect network path\n        log.warning(\"malformed Content-Length from GitHub path; proxy suspected\")\n        raise\n    raise","preventionTips":["Bypass SSL-inspecting proxies and captive networks for api.github.com.","When mocking responses in tests, return headers as a dict of clean digit strings or omit Content-Length entirely.","Treat this error as a security signal as often as a reliability one — a mangled Content-Length means something is rewriting responses."],"tags":["http","headers","fetch-star-count","proxy","validation"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}