benweet/stackedit · error · Error

WordPress account ID not expected.

Error message

WordPress account ID not expected.

What it means

startOauth2 fetches the WordPress.com user profile (rest/v1.1/me) and compares `${body.ID}` with an optional expected sub. On mismatch it throws 'WordPress account ID not expected.' so a token for a different WordPress.com account is never attached to an existing entry.

Source

Thrown at src/services/providers/helpers/wordpressHelper.js:41

    // Get an OAuth2 code
    const { accessToken, expiresIn } = await networkSvc.startOauth2(
      'https://public-api.wordpress.com/oauth2/authorize',
      {
        client_id: clientId,
        response_type: 'token',
        scope: 'global',
      },
      silent,
    );

    // Call the user info endpoint
    const body = await request({ accessToken }, {
      url: 'https://public-api.wordpress.com/rest/v1.1/me',
    });

    // Check the returned sub consistency
    if (sub && `${body.ID}` !== sub) {
      throw new Error('WordPress account ID not expected.');
    }
    // Build token object including scopes and sub
    const token = {
      accessToken,
      expiresOn: Date.now() + (expiresIn * 1000),
      name: body.display_name,
      sub: `${body.ID}`,
    };
    // Add token to wordpress tokens
    store.dispatch('data/addWordpressToken', token);
    return token;
  },
  async refreshToken(token) {
    const { sub } = token;
    const lastToken = store.getters['data/wordpressTokensBySub'][sub];

    if (lastToken.expiresOn > Date.now() + tokenExpirationMargin) {
      return lastToken;

View on GitHub (pinned to 6dce2a5e36)

Solutions

  1. Sign out of WordPress.com in the browser (or use a private window) and reconnect with the intended account.
  2. Clear the stored WordPress token/sub and re-run the OAuth flow to bind the current account.
  3. Verify the sub value passed into startOauth2 matches the stored token's sub field.
  4. If refreshing, delete the stale refresh token and perform a fresh authorization.

Example fix

// before
const token = await wordpressHelper.startOauth2(code, sub);
// after
try {
  const token = await wordpressHelper.startOauth2(code, sub);
} catch (e) {
  if (e.message === 'WordPress account ID not expected.') {
    // reconnect without expecting a previous sub
    const token = await wordpressHelper.startOauth2(code, undefined);
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const body = await request({ accessToken }, { url: 'https://public-api.wordpress.com/rest/v1.1/me' });
if (expectedSub && `${body.ID}` !== expectedSub) {
  throw new Error(`WordPress account mismatch: expected ${expectedSub}, got ${body.ID}`);
}

Type guard

function isExpectedWordPressId(meBody, expectedSub) {
  return !expectedSub || `${meBody.ID}` === expectedSub;
}

Try / catch

try {
  const token = await wordpressHelper.startOauth2(code, sub);
} catch (err) {
  if (err.message === 'WordPress account ID not expected.') {
    // re-authenticate with the correct WordPress.com account
  } else throw err;
}

Prevention

When it happens

Trigger: OAuth callback (token) or refreshToken when the authenticated WordPress.com user's numeric ID differs from the stored sub — e.g. the browser session belongs to another WordPress account, or a refresh token was issued to a different user.

Common situations: Multiple WordPress.com accounts in one browser; shared machine where a colleague's WordPress session is active; stored sub copied from another environment; WordPress account migration/merge changing the ID mapping.

Related errors


AI-assisted analysis of benweet/stackedit@6dce2a5e36 (2026-09-01). Data as JSON: /api/errors/b5a04bc3a2ee3ade. Report an issue: GitHub.