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.
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.
- Gist file not found.
- Git tree too big. Please remove some files in the…
- GitLab account ID not expected.
- Google account ID not expected.
AI-assisted analysis of benweet/stackedit@6dce2a5e36 (2026-09-01).
Data as JSON: /api/errors/d3248c64ba02bcc5.
Report an issue: GitHub.
Appendix: 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)