decolua/9router · error · Error
Failed to fetch GitHub usage: ${error.message}
Error message
Failed to fetch GitHub usage: ${error.message} What it means
This is the outer catch-all of getGitHubUsage: any error thrown inside the function (including errors 111 and 112) is re-thrown prefixed with 'Failed to fetch GitHub usage:'. The original message is preserved via error.message, so the root cause (missing token, HTTP error, JSON parse failure) is chained in the text.
Source
Thrown at open-sse/services/usage/github.js:87
chat: {
used: usedQuotas.chat || 0,
total: monthlyQuotas.chat || 0,
unlimited: false,
resetAt,
},
completions: {
used: usedQuotas.completions || 0,
total: monthlyQuotas.completions || 0,
unlimited: false,
resetAt,
},
},
};
}
return { message: "GitHub Copilot connected. Unable to parse quota data." };
} catch (error) {
throw new Error(`Failed to fetch GitHub usage: ${error.message}`);
}
}
function formatGitHubQuotaSnapshot(quota) {
if (!quota) return { used: 0, total: 0, unlimited: true };
return {
used: quota.entitlement - quota.remaining,
total: quota.entitlement,
remaining: quota.remaining,
unlimited: quota.unlimited || false,
};
}
View on GitHub (pinned to 90b52e06ff)
Solutions
- Strip the prefix and inspect error.message to find the root cause (missing token vs API error)
- If the cause is a missing/invalid token, re-run the GitHub OAuth authorization flow
- Guard the call in try/catch and render a 'reconnect GitHub' prompt instead of crashing the usage panel
- Ensure the upstream body is JSON — HTML error pages will fail at response.json()
Example fix
// before
const usage = await getGitHubUsage(token, data, proxy);
// after
let usage;
try {
usage = await getGitHubUsage(token, data, proxy);
} catch (e) {
usage = { error: true, message: e.message, reconnectNeeded: /access token/i.test(e.message) };
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!account?.accessToken) return { reconnect: true, quotas: null }; Try / catch
try {
usage = await getGitHubUsage(token, data, proxy);
} catch (e) {
// e.message is the prefixed chain: inspect inner cause
const cause = e.message.replace(/^Failed to fetch GitHub usage: /, "");
return { error: cause, reconnectNeeded: /access token|API error: 40/.test(cause) };
} Prevention
- Catch this wrapper at the usage-handler boundary and degrade gracefully
- Parse the inner message to distinguish auth vs network causes
- Never let a usage fetch crash the main routing path
- Cache last-known usage so the UI survives transient failures
When it happens
Trigger: Any failure path inside getGitHubUsage: falsy accessToken, non-OK upstream response, response.json() failing on a non-JSON body, or an unexpected runtime error while parsing quota_snapshots / quota_reset_date fields.
Common situations: Callers seeing this wrapper in logs/usage handlers; double wrapping when the usage handler itself adds another prefix; the inner cause being an expired token or upstream 4xx.
Related errors
- No GitHub access token available. Please re-authorize the co
- GitHub API error: ${error}
- [Claude Usage] OAuth endpoint returned ${oauthResponse.statu
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/f944aa4ae494d756.
Report an issue: GitHub.