can1357/oh-my-pi · error · HTTPException
{exc.message}
Error message
{exc.message} What it means
After a successful authenticated_login call to the proxy, the proxy asks the upstream GitHub API for the authenticated user's login. If the upstream GitHubClient raises GitHubError, the proxy forwards its status and message as an HTTPException — so this error surfaces the real GitHub API failure (401 bad credentials, 403 rate limit, 5xx, etc.) through the proxy.
Source
Thrown at python/robomp/src/proxy/server.py:476
extra={"reason": result.reason, "path": request.url.path},
)
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "unauthenticated")
return body
# ---- meta ----
@app.get("/healthz")
async def healthz() -> dict[str, str]:
return {"status": "ok"}
# ---- reads ----
@app.get("/gh/v1/authenticated_login")
async def authenticated_login(request: Request) -> dict[str, str]:
await _authenticate(request)
github: GitHubClient = request.app.state.github
try:
login = await github.get_authenticated_login()
except GitHubError as exc:
raise HTTPException(exc.status, exc.message) from exc
return {"login": login}
@app.get("/gh/v1/repo")
async def get_repo(request: Request, repo: str) -> JSONResponse:
await _authenticate(request)
github: GitHubClient = request.app.state.github
try:
info = await github.get_repo(repo)
except GitHubError as exc:
return _gh_error_response(exc)
return JSONResponse(_serialize(info))
@app.get("/gh/v1/workflow_runs")
async def list_workflow_runs(request: Request, repo: str, head_sha: str) -> JSONResponse:
await _authenticate(request)
_validate_repo_name(repo)
github: GitHubClient = request.app.state.github
try:View on GitHub (pinned to 9690622007)
Solutions
- Read the forwarded message/status in the response to identify the upstream cause
- Re-authenticate or regenerate the token with the required scopes (repo / read:org as needed)
- Wait for the rate-limit reset or use a token with a higher limit if the status is 403 rate-limited
- Retry on 5xx after a short backoff; check the GitHub status page for incidents
Example fix
// before
const { login } = await res.json(); // throws on 4xx/5xx
// after
const res = await fetch(proxy + "/gh/v1/login", { headers });
if (!res.ok) {
const detail = await res.text();
if (res.status === 403) await backoffForRateLimit(res);
throw new Error(`login failed (${res.status}): ${detail}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// cheap upstream probe before relying on the token
const probe = await fetch("https://api.github.com/user", { headers: { Authorization: `Bearer ${token}` } });
if (probe.status === 403 && probe.headers.get("x-ratelimit-remaining") === "0") {
throw new Error(`rate limited until ${new Date(+probe.headers.get("x-ratelimit-reset") * 1000)}`);
} Try / catch
const res = await fetch(proxy + "/gh/v1/login", { headers });
if (!res.ok) {
const message = await res.text();
if (res.status === 401 || res.status === 403) throw new Error(`upstream GitHub rejected token (${res.status}): ${message}`);
if (res.status >= 500) throw new Error(`GitHub server error, retry later: ${message}`);
} Prevention
- Grant fine-grained PATs the scopes the proxy endpoints need
- Authorize tokens for org SSO
- Monitor rate limits and rotate tokens before expiry
- Retry 5xx with backoff; surface 4xx messages to the user
When it happens
Trigger: GET /gh/v1/login with a token that passes local auth but fails upstream: revoked mid-flight, lacking required scopes, rate-limited (403 with X-RateLimit-Remaining: 0), or GitHub returning a server error.
Common situations: Fine-grained PAT without account-level read permission; org SSO not authorized for the token; exhausted API rate limit on shared runners; transient GitHub 5xx incidents.
Related errors
- GitHub API rate limit exceeded while fetching release metada
- GitHub API error: ${response.status}
- Too many pending authorization requests. Please try again la
- OpenCode Go usage endpoint returned ${response.status}${deta
- Umans usage endpoint returned ${response.status} ${response.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3763b846bc5f54cf.
Report an issue: GitHub.