benweet/stackedit · error · Error
GitHub account ID not expected.
Error message
GitHub account ID not expected.
What it means
After a GitHub OAuth2 exchange, startOauth2 compares the authenticated user's id with the `sub` claim of the app token. If `${user.id}` !== sub, githubHelper throws at src/services/providers/helpers/githubHelper.js:104 because the GitHub account that authorized the app differs from the identity the token was minted for. This guards against binding workspace data to the wrong GitHub identity.
Source
Thrown at src/services/providers/helpers/githubHelper.js:104
})).body;
// Call the user info endpoint
const user = (await networkSvc.request({
method: 'GET',
url: 'https://api.github.com/user',
headers: {
Authorization: `token ${accessToken}`,
},
})).body;
userSvc.addUserInfo({
id: `${subPrefix}:${user.id}`,
name: user.login,
imageUrl: user.avatar_url || '',
});
// Check the returned sub consistency
if (sub && `${user.id}` !== sub) {
throw new Error('GitHub account ID not expected.');
}
// Build token object including scopes and sub
const token = {
scopes,
accessToken,
name: user.login,
sub: `${user.id}`,
repoFullAccess: scopes.includes('repo'),
};
// Add token to github tokens
store.dispatch('data/addGithubToken', token);
return token;
},
async addAccount(repoFullAccess = false) {
const token = await this.startOauth2(getScopes({ repoFullAccess }));
badgeSvc.addBadge('addGitHubAccount');View on GitHub (pinned to 6dce2a5e36)
Solutions
- Reconnect the provider while logged into the intended GitHub account (use a private window if multiple accounts are signed in).
- Clear the saved GitHub token and restart the OAuth flow so sub is derived from the fresh exchange.
- Verify the sub value fed into the token construction matches the account that completed authorization.
- Check the token's stored sub in app storage and remove mismatches before retrying.
Example fix
// before
if (sub && `${user.id}` !== sub) {
throw new Error('GitHub account ID not expected.');
}
// after
if (sub && `${user.id}` !== sub) {
throw new Error(`GitHub account ID not expected (authorized ${user.id}, expected ${sub}). Sign in with the correct GitHub account.`);
} Defensive patterns
Strategy: try-catch
Validate before calling
function savedGitHubSubMatches(sub) {
const saved = readSavedProviderToken('github');
return !saved || !saved.sub || saved.sub === sub;
} Type guard
function isGitHubAccountMismatch(err) {
return err instanceof Error && /account ID not expected/i.test(err.message);
} Try / catch
try {
await githubHelper.startOauth2(...);
} catch (err) {
if (isGitHubAccountMismatch(err)) {
clearStoredTokens('github');
promptReauthWithCorrectAccount();
}
} Prevention
- Ensure the browser is signed into the intended GitHub account before authorizing.
- Drop old tokens when switching between personal and work accounts.
- Derive sub from the same OAuth exchange as the access token.
- Offer an explicit 'switch account' flow that clears stored tokens first.
When it happens
Trigger: `${user.id}` !== sub in startOauth2: user authorized with a different GitHub account than the one associated with the token's sub; stale sub from a previously saved token reused in a new flow; multiple GitHub accounts in the browser.
Common situations: Developers with personal and work GitHub accounts switching between them; re-auth after account migration/renaming with cached tokens; shared-machine browser sessions.
Related errors
- Dropbox account ID not expected.
- The authorize window was blocked.
- Git tree too big. Please remove some files in the repository
- Gist file not found.
- GitLab account ID not expected.
AI-assisted analysis of benweet/stackedit@6dce2a5e36 (2026-09-01).
Data as JSON: /api/errors/d3248c64ba02bcc5.
Report an issue: GitHub.