decolua/9router · error · Error
Failed to get user info: ${error}
Error message
Failed to get user info: ${error} What it means
GitHubService.getUserInfo() calls GET https://api.github.com/user with the freshly obtained access token to fetch the authenticated user's profile. A non-OK response causes the raw body to be thrown as `Failed to get user info: ${error}`. Since the token was just minted by the device flow, this usually indicates a network/API problem rather than bad credentials — but a revoked or scope-less token will also fail here with 401.
Source
Thrown at src/lib/oauth/services/github.js:138
return await response.json();
}
/**
* Get user info using GitHub access token
*/
async getUserInfo(accessToken) {
const response = await fetch(`${GITHUB_CONFIG.userInfoUrl}`, {
headers: {
Authorization: `Bearer ${accessToken}`, // GitHub API typically uses Bearer
Accept: "application/json",
"X-GitHub-Api-Version": GITHUB_CONFIG.apiVersion,
"User-Agent": GITHUB_CONFIG.userAgent,
},
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Failed to get user info: ${error}`);
}
return await response.json();
}
/**
* Complete GitHub Copilot authentication flow
*/
async authenticate() {
try {
// Get device code
const deviceResponse = await this.getDeviceCode();
// Poll for access token
const tokenResponse = await this.pollAccessToken(
deviceResponse.device_code,
deviceResponse.verification_uri,
deviceResponse.user_codeView on GitHub (pinned to 90b52e06ff)
Solutions
- Inspect the embedded body for a 403 rate-limit message; if so, wait for the rate-limit window or authenticate from a different IP.
- Re-run the device-flow authentication to obtain a fresh token, then retry.
- Verify api.github.com is reachable (curl -i https://api.github.com/user with the token) and no proxy strips Authorization.
- Retry later if GitHub status (githubstatus.com) reports an API incident.
Example fix
// before
if (!response.ok) {
const error = await response.text();
throw new Error(`Failed to get user info: ${error}`);
}
// after
if (!response.ok) {
const error = await response.text();
throw new Error(`Failed to get user info (HTTP ${response.status}): ${error}`);
} Defensive patterns
Strategy: retry
Validate before calling
async function assertUserFetchable(accessToken) {
const res = await fetch('https://api.github.com/user', {
headers: { Authorization: `Bearer ${accessToken}`, Accept: 'application/json', 'User-Agent': 'app' },
});
if (res.status === 403 && res.headers.get('x-ratelimit-remaining') === '0') {
throw new Error('GitHub API rate limit exhausted — wait for reset before authenticating');
}
if (!res.ok) throw new Error(`GitHub /user pre-check failed: HTTP ${res.status}`);
} Type guard
function isGitHubUser(data) {
return data !== null && typeof data === 'object' && typeof data.login === 'string' && typeof data.id === 'number';
} Try / catch
try {
const userInfo = await service.getUserInfo(accessToken);
} catch (err) {
if (err.message.startsWith('Failed to get user info')) {
console.error('GitHub /user call failed — check rate limits (403), token validity (401), or api.github.com reachability, then retry.');
}
throw err;
} Prevention
- Retry with backoff on 5xx and on 403 rate-limit responses (respect x-ratelimit-reset).
- Run heavy automation from IPs not shared across many unauthenticated GitHub calls.
- Confirm proxies don't strip the Authorization header when calling api.github.com.
- Check githubstatus.com for API incidents before scheduled auth runs.
When it happens
Trigger: GET to api.github.com/user returns non-2xx: 401 (bad/insufficiently-scoped token), 403 (rate limit exhausted for the IP), 5xx from GitHub, or an intercepted body from a proxy/portal.
Common situations: Shared IP (corporate NAT/CI) hitting GitHub's unauthenticated rate limits; a proxy stripping the Authorization header; GitHub API incident; User-Agent or X-GitHub-Api-Version rejected by an API gateway.
Related errors
- Google translate fetch failed: ${res.status}
- Failed to get device code: ${error}
- Failed to get Copilot token: ${error}
- Failed to fetch image: ${res.status}
- Bing translator fetch failed: ${res.status}
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/a8eb89d9721970f0.
Report an issue: GitHub.