666ghj/MiroFish · error · FetchError
GITHUB_TOKEN is missing or invalid
Error message
GITHUB_TOKEN is missing or invalid
What it means
Input validation at the top of fetch_star_count: the token must be non-empty, at most 4096 characters, and contain no CR or LF. The newline checks exist because the token is interpolated into an Authorization header — an embedded \r/\n would allow header injection (request splitting). This is a guard against a malformed GITHUB_TOKEN, not a GitHub-side failure.
Source
Thrown at scripts/fetch_star_count.py:74
def _read_response(response: Any) -> bytes:
raw_length = response.headers.get("Content-Length")
if raw_length is not None:
try:
content_length = int(raw_length, 10)
except (TypeError, ValueError) as exc:
raise FetchError("GitHub API returned invalid response metadata") from exc
if content_length < 0 or content_length > MAX_HTTP_BYTES:
raise FetchError("GitHub API response exceeded the size limit")
payload = response.read(MAX_HTTP_BYTES + 1)
if len(payload) > MAX_HTTP_BYTES:
raise FetchError("GitHub API response exceeded the size limit")
return payload
def fetch_star_count(token: str, opener: Any | None = None) -> int:
if not token or len(token) > 4_096 or "\r" in token or "\n" in token:
raise FetchError("GITHUB_TOKEN is missing or invalid")
request = urllib.request.Request(
API_URL,
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {token}",
"User-Agent": "Repository-Star-History-Fetcher",
"X-GitHub-Api-Version": API_VERSION,
},
method="GET",
)
client = opener or _build_opener()
try:
response = client.open(request, timeout=TIMEOUT_SECONDS)
except urllib.error.HTTPError as exc:
status = exc.code
exc.close()
raise _status_error(status) from NoneView on GitHub (pinned to b5b53acc57)
Solutions
- Check the secret wiring: in GitHub Actions confirm the step has env: GITHUB_TOKEN: ${{ secrets.X }} (or uses the auto GITHUB_TOKEN correctly); locally confirm it is exported in the shell running the script.
- Strip the value before use: export GITHUB_TOKEN="$(printf '%s' "$GITHUB_TOKEN" | tr -d '\r\n')" — the script intentionally does not strip, so fix the source of the newline.
- Verify length/format: a classic ghp_ PAT is ~40 chars; if yours is >4096 or multiline, the wrong value (e.g. a file path or JSON) was assigned.
Example fix
# before (CI step)
- run: python scripts/fetch_star_count.py
env:
GITHUB_TOKEN: ${{ secrets.STAR_HISTORY_TOKEN }}
# secret stored with trailing newline -> error
# after: sanitize once at the call site (or fix the secret)
- run: python scripts/fetch_star_count.py
env:
GITHUB_TOKEN: ${{ secrets.STAR_HISTORY_TOKEN }}
# and in the wrapper: GITHUB_TOKEN="${GITHUB_TOKEN//$'\n'/}" python scripts/fetch_star_count.py Defensive patterns
Strategy: validation
Validate before calling
import os
TOKEN_MAX = 4_096
token = os.environ.get("GITHUB_TOKEN", "")
if not token or len(token) > TOKEN_MAX or "\r" in token or "\n" in token:
raise SystemExit(
"GITHUB_TOKEN must be set, <=4096 chars, without newlines "
"(check the CI secret for a trailing newline)"
)
count = fetch_star_count(token) Type guard
def is_valid_github_token(value: object) -> bool:
"""True when value can be safely placed in an Authorization header."""
return (
isinstance(value, str)
and 0 < len(value) <= 4_096
and "\r" not in value
and "\n" not in value
) Try / catch
try:
count = fetch_star_count(os.environ.get("GITHUB_TOKEN", ""))
except FetchError as exc:
if exc.args[0] == "GITHUB_TOKEN is missing or invalid":
raise SystemExit("CI: add GITHUB_TOKEN to the step env / strip trailing newline")
raise Prevention
- Fail fast on the token before any network call — validate shape at the entry point of your wrapper.
- When pasting secrets into CI, use the provider's secret store rather than inline YAML to avoid stray newlines.
- Log token length (never the token) in debug output to catch truncation or multi-value assignment early.
When it happens
Trigger: GITHUB_TOKEN unset or empty (os.environ.get('GITHUB_TOKEN', '') yields ''); a token with trailing newline/whitespace pasted from a CI secret (the classic trailing \n in GitHub Actions/GitLab CI secrets); a token longer than 4096 chars; a multiline value accidentally assigned.
Common situations: CI scheduled workflow missing the GITHUB_TOKEN secret in env:; secret copied with quotes/newline into .env; runner injecting the variable with surrounding whitespace; passing the wrong env var name.
Related errors
- GitHub API redirect was refused
- ZEP_API_KEY 未配置
- 缺少 API Key 配置,请在项目根目录 .env 文件中设置 LLM_API_KEY
- 缺少 API Key 配置,请在项目根目录 .env 文件中设置 LLM_API_KEY
- 缺少 API Key 配置,请在项目根目录 .env 文件中设置 LLM_API_KEY
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/871d93ec80f9a564.
Report an issue: GitHub.