{"record":{"id":"c81c72c62484a6ab","repo":"benweet/stackedit","slug":"zendesk-account-id-not-expected","errorCode":null,"errorMessage":"Zendesk account ID not expected.","messagePattern":"Zendesk account ID not expected\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/providers/helpers/zendeskHelper.js","lineNumber":39,"sourceCode":"    const { accessToken } = await networkSvc.startOauth2(\n      `https://${subdomain}.zendesk.com/oauth/authorizations/new`,\n      {\n        client_id: clientId,\n        response_type: 'token',\n        scope: 'read hc:write',\n      },\n      silent,\n    );\n\n    // Call the user info endpoint\n    const { user } = await request({ accessToken }, {\n      url: `https://${subdomain}.zendesk.com/api/v2/users/me.json`,\n    });\n    const uniqueSub = `${subdomain}/${user.id}`;\n\n    // Check the returned sub consistency\n    if (sub && uniqueSub !== sub) {\n      throw new Error('Zendesk account ID not expected.');\n    }\n\n    // Build token object including scopes and sub\n    const token = {\n      accessToken,\n      name: user.name,\n      subdomain,\n      sub: uniqueSub,\n    };\n\n    // Add token to zendesk tokens\n    store.dispatch('data/addZendeskToken', token);\n    return token;\n  },\n  async addAccount(subdomain, clientId) {\n    const token = await this.startOauth2(subdomain, clientId);\n    badgeSvc.addBadge('addZendeskAccount');\n    return token;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/benweet/stackedit/blob/6dce2a5e36b755a0c244522b48a06c91a2df0f59/src/services/providers/helpers/zendeskHelper.js#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst token = await zendeskHelper.startOauth2(code, sub, subdomain);\n// after\ntry {\n  const token = await zendeskHelper.startOauth2(code, sub, subdomain);\n} catch (e) {\n  if (e.message === 'Zendesk account ID not expected.') {\n    // subdomain or user changed; rebind\n    const token = await zendeskHelper.startOauth2(code, undefined, subdomain);\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const user = (await request({ accessToken }, { url: `https://${subdomain}.zendesk.com/api/v2/users/me.json` })).body.user;\nconst uniqueSub = `${subdomain}/${user.id}`;\nif (expectedSub && uniqueSub !== expectedSub) {\n  throw new Error(`Zendesk subdomain/user mismatch: expected ${expectedSub}, got ${uniqueSub}`);\n}","typeGuard":"function isExpectedZendeskSub(user, subdomain, expectedSub) {\n  return !expectedSub || `${subdomain}/${user.id}` === expectedSub;\n}","tryCatchPattern":"try {\n  const token = await zendeskHelper.startOauth2(code, sub, subdomain);\n} catch (err) {\n  if (err.message === 'Zendesk account ID not expected.') {\n    // subdomain or user changed; clear stored sub and re-authorize\n  } else throw err;\n}","preventionTips":["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"],"tags":["zendesk","oauth2","account-mismatch","subdomain"],"backgroundTag":"oauth-account-mismatch","analyzedSha":"6dce2a5e36b755a0c244522b48a06c91a2df0f59","analyzedAt":"2026-09-01T00:49:23.866Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}