benweet/stackedit · error · Error
Zendesk account ID not expected.
Error message
Zendesk account ID not expected.
What it means
startOauth2 builds a per-instance unique sub (`${subdomain}/${user.id}`) from the Zendesk /users/me.json response and compares it with an optional expected sub. A mismatch throws 'Zendesk account ID not expected.', preventing a token from a different Zendesk instance or user from being bound to an existing entry.
Source
Thrown at src/services/providers/helpers/zendeskHelper.js:39
const { accessToken } = await networkSvc.startOauth2(
`https://${subdomain}.zendesk.com/oauth/authorizations/new`,
{
client_id: clientId,
response_type: 'token',
scope: 'read hc:write',
},
silent,
);
// Call the user info endpoint
const { user } = await request({ accessToken }, {
url: `https://${subdomain}.zendesk.com/api/v2/users/me.json`,
});
const uniqueSub = `${subdomain}/${user.id}`;
// Check the returned sub consistency
if (sub && uniqueSub !== sub) {
throw new Error('Zendesk account ID not expected.');
}
// Build token object including scopes and sub
const token = {
accessToken,
name: user.name,
subdomain,
sub: uniqueSub,
};
// Add token to zendesk tokens
store.dispatch('data/addZendeskToken', token);
return token;
},
async addAccount(subdomain, clientId) {
const token = await this.startOauth2(subdomain, clientId);
badgeSvc.addBadge('addZendeskAccount');
return token;View on GitHub (pinned to 6dce2a5e36)
Solutions
- Reconnect through the original Zendesk subdomain and user account that matches the stored sub.
- If the subdomain legitimately changed, clear the stored sub and re-authorize to establish a new one.
- Sign out of other Zendesk sessions in the browser or use a private window to force the right account.
- Verify the stored sub string format (`subdomain/userId`) matches what current code builds.
Example fix
// before
const token = await zendeskHelper.startOauth2(code, sub, subdomain);
// after
try {
const token = await zendeskHelper.startOauth2(code, sub, subdomain);
} catch (e) {
if (e.message === 'Zendesk account ID not expected.') {
// subdomain or user changed; rebind
const token = await zendeskHelper.startOauth2(code, undefined, subdomain);
} else throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const user = (await request({ accessToken }, { url: `https://${subdomain}.zendesk.com/api/v2/users/me.json` })).body.user;
const uniqueSub = `${subdomain}/${user.id}`;
if (expectedSub && uniqueSub !== expectedSub) {
throw new Error(`Zendesk subdomain/user mismatch: expected ${expectedSub}, got ${uniqueSub}`);
} Type guard
function isExpectedZendeskSub(user, subdomain, expectedSub) {
return !expectedSub || `${subdomain}/${user.id}` === expectedSub;
} Try / catch
try {
const token = await zendeskHelper.startOauth2(code, sub, subdomain);
} catch (err) {
if (err.message === 'Zendesk account ID not expected.') {
// subdomain or user changed; clear stored sub and re-authorize
} else throw err;
} Prevention
- Persist the subdomain alongside the token and validate it before refreshing
- When a Zendesk URL changes, treat stored subs as invalid and re-link
- Use a private window or explicit logout to avoid picking up another user's Zendesk session
- Compare subdomain and user id separately to give precise mismatch messages
When it happens
Trigger: OAuth callback (token) when the authenticated Zendesk user's subdomain/user.id composite differs from the stored sub — e.g. signing into a different Zendesk subdomain, or a different user on the same instance.
Common situations: Multiple Zendesk subdomains (company changed its Zendesk URL); agent vs admin accounts in the same browser; the subdomain config changed after the sub was stored; Zendesk user re-created with a new id.
Related errors
- GitLab account ID not expected.
- Google account ID not expected.
- WordPress account ID not expected.
- Dropbox account ID not expected.
- GitHub account ID not expected.
AI-assisted analysis of benweet/stackedit@6dce2a5e36 (2026-09-01).
Data as JSON: /api/errors/c81c72c62484a6ab.
Report an issue: GitHub.