666ghj/MiroFish · error · FetchError
GitHub API response could not be processed
Error message
GitHub API response could not be processed
What it means
Catch-all for any non-FetchError, non-OSError/TimeoutError exception raised while handling a successful response (the with response block): geturl()/getcode() returning unexpected types, _read_response raising something other than FetchError, or defects in custom response objects supplied by a custom opener. It separates 'response obtained but processing crashed unexpectedly' from the typed failure paths.
Source
Thrown at scripts/fetch_star_count.py:111
except (urllib.error.URLError, TimeoutError, OSError):
raise FetchError("GitHub API network request failed") from None
except Exception:
raise FetchError("GitHub API request could not be started") from None
try:
with response:
if response.geturl() != API_URL:
raise FetchError("GitHub API redirect was refused")
status = response.getcode()
if status != 200:
raise _status_error(status)
payload = _read_response(response)
except FetchError:
raise
except (TimeoutError, OSError):
raise FetchError("GitHub API response could not be read") from None
except Exception:
raise FetchError("GitHub API response could not be processed") from None
try:
document = json.loads(payload)
except (UnicodeDecodeError, json.JSONDecodeError, ValueError):
raise FetchError("GitHub API returned malformed JSON") from None
if not isinstance(document, dict):
raise FetchError("GitHub API response had an unexpected shape")
count = document.get("stargazers_count")
if type(count) is not int or count < 0:
raise FetchError("GitHub API returned an invalid stargazers_count")
return count
def main(argv: list[str] | None = None) -> int:
arguments = sys.argv[1:] if argv is None else argv
if arguments:
print("error: this command accepts no arguments", file=sys.stderr)View on GitHub (pinned to b5b53acc57)
Solutions
- Reproduce outside the wrapper (temporarily remove the except Exception) to see the original traceback and fix the underlying object.
- Make custom openers/responses implement the minimal real interface: geturl(), getcode(), headers (email.message.Message-like), read(n), context manager.
- In tests, raise OSError/TimeoutError subclasses for I/O failures so they map to the precise messages instead.
Defensive patterns
Strategy: try-catch
Validate before calling
def response_is_httpresponse_like(obj: object) -> bool:
"""Minimal interface fetch_star_count needs from a response object."""
return all(
callable(getattr(obj, name, None))
for name in ("geturl", "getcode", "read")
) and hasattr(obj, "headers") and hasattr(obj, "__enter__") Try / catch
try:
count = fetch_star_count(token, opener=fake_opener)
except FetchError as exc:
if exc.args[0] == "GitHub API response could not be processed":
# response handler crashed unexpectedly; call handler directly to debug
raise Prevention
- Make test response doubles real http.client.HTTPResponse instances or dataclass fakes with the full interface.
- Do not swallow the original exception in your own wrappers — this branch intentionally hides it, so debug with the wrapper removed.
- Consider this error a defect marker: none of GitHub's real responses should reach it.
When it happens
Trigger: Passing a mock opener whose response object lacks proper geturl/getcode/read semantics and raises AttributeError; _read_response hitting a header object whose .get returns a value that int() mishandles in an unanticipated way; future urllib behavior changes.
Common situations: Test doubles not matching the http.client.HTTPResponse interface; custom openers wrapping other HTTP clients incompletely.
Related errors
- GitHub API request could not be started
- GitHub API returned invalid response metadata
- GitHub API response exceeded the size limit
- GITHUB_TOKEN is missing or invalid
- GitHub API network request failed
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/9505a3ee0d90703e.
Report an issue: GitHub.