benweet/stackedit · critical · Error

Synchronization failed due to token inconsistency.

Error message

Synchronization failed due to token inconsistency.

What it means

During synchronization the app keeps a localSettings.syncSub identifying which account sub owns the sync data. If a sync token's sub differs from the previously stored syncSub, syncSvc throws 'Synchronization failed due to token inconsistency.' to stop one account from writing into another account's synced data.

Source

Thrown at src/services/syncSvc.js:631

};

/**
 * Sync the whole workspace with the main provider and the current file explicit locations.
 */
const syncWorkspace = async (skipContents = false) => {
  try {
    const workspace = store.getters['workspace/currentWorkspace'];
    const syncContext = new SyncContext();

    // Store the sub in the DB since it's not safely stored in the token
    const syncToken = store.getters['workspace/syncToken'];
    const localSettings = store.getters['data/localSettings'];
    if (!localSettings.syncSub) {
      store.dispatch('data/patchLocalSettings', {
        syncSub: syncToken.sub,
      });
    } else if (localSettings.syncSub !== syncToken.sub) {
      throw new Error('Synchronization failed due to token inconsistency.');
    }

    const changes = await workspaceProvider.getChanges();

    // Apply changes
    applyChanges(workspaceProvider.prepareChanges(changes));
    workspaceProvider.onChangesApplied();

    // Prevent from sending items too long after changes have been retrieved
    const ifNotTooLate = tooLateChecker(restartSyncAfter);

    // Find and save one item to save
    await utils.awaitSome(() => ifNotTooLate(async () => {
      const storeItemMap = {
        ...store.state.file.itemsById,
        ...store.state.folder.itemsById,
        ...store.state.syncLocation.itemsById,
        ...store.state.publishLocation.itemsById,

View on GitHub (pinned to 6dce2a5e36)

Solutions

  1. Reconnect the sync location with the account whose sub matches localSettings.syncSub.
  2. Clear/patch localSettings.syncSub (or reset local settings) so the next sync binds to the current account, accepting that the data owner changes.
  3. Verify which account the workspace data actually belongs to before overriding syncSub to avoid cross-account contamination.
  4. If the account was permanently switched, migrate/export the workspace data and start a fresh sync location.

Example fix

// before
await store.dispatch('data/patchLocalSettings', { syncSub: syncToken.sub }); // silently skipped when stale
await sync();
// after
const localSettings = store.getters['data/localSettings'];
if (localSettings.syncSub && localSettings.syncSub !== syncToken.sub) {
  await store.dispatch('data/patchLocalSettings', { syncSub: syncToken.sub }); // deliberate owner switch
}
await sync();
Defensive patterns

Strategy: validation

Validate before calling

const localSettings = store.getters['data/localSettings'];
const syncTokenSub = syncToken && syncToken.sub;
if (localSettings.syncSub && syncTokenSub && localSettings.syncSub !== syncTokenSub) {
  // resolve deliberately before syncing:
  // reconnect with the original account, or confirm a switch and patch syncSub
}

Type guard

function isSyncSubConsistent(localSettings, syncToken) {
  return Boolean(syncToken && syncToken.sub && (!localSettings.syncSub || localSettings.syncSub === syncToken.sub));
}

Try / catch

try {
  await syncSvc.sync();
} catch (err) {
  if (err.message.includes('token inconsistency')) {
    // surface an account-switch dialog instead of auto-overwriting syncSub
  } else throw err;
}

Prevention

When it happens

Trigger: Running sync (syncSvc) when the current workspace provider's sync token belongs to a different account than localSettings.syncSub — e.g. switching main/secondary accounts, restoring data from another account, or a stale localSettings entry after an account change.

Common situations: Reconnecting the sync location with a different Google/GitLab account; importing a workspace export from another user; localSettings surviving an account switch and pointing at the old sub; team setup where two users share a machine profile.

Related errors


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