actualbudget/actual · error

SYNC_ERROR

SYNC_ERROR

Error message

SYNC_ERROR

What it means

The default branch of getFailedSyncError: any bank_sync_status value not explicitly handled resolves to SYNC_ERROR. It is a generic catch-all meaning the last bank sync failed for an unclassified reason and the specific provider error should be inspected in logs.

Source

Thrown at packages/desktop-client/src/accounts/syncStatus.ts:36

  switch (account.bank_sync_status) {
    case 'reauth-required':
      if (account.account_sync_source === 'simpleFin') {
        return { type: 'INVALID_ACCESS_TOKEN', code: 'INVALID_ACCESS_TOKEN' };
      }
      return { type: 'ITEM_ERROR', code: 'ITEM_LOGIN_REQUIRED' };
    case 'attention-required':
      return {
        type: 'ACCOUNT_NEEDS_ATTENTION',
        code: 'ACCOUNT_NEEDS_ATTENTION',
      };
    case 'rate-limit-exceeded':
      return { type: 'RATE_LIMIT_EXCEEDED', code: 'RATE_LIMIT_EXCEEDED' };
    case 'timed-out':
      return { type: 'TIMED_OUT', code: 'TIMED_OUT' };
    case 'account-missing':
      return { type: 'ACCOUNT_MISSING', code: 'ACCOUNT_MISSING' };
    default:
      return { type: 'SYNC_ERROR', code: 'SYNC_ERROR' };
  }
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Check server/bank-sync logs for the underlying provider error
  2. Verify the server's bank_sync_status values match the cases handled in syncStatus.ts (version drift)
  3. Run a fresh manual sync and re-read the resulting status
  4. If a new status value exists upstream, add an explicit case to getFailedSyncError instead of relying on the default

Example fix

// before
// server writes 'provider-outage', client switch has no case -> SYNC_ERROR
// after
if (getFailedSyncError(account).code === 'SYNC_ERROR') {
  inspectServerLogs(account.id); // find the real provider error
}
Defensive patterns

Strategy: type-guard

Validate before calling

const KNOWN_STATUSES = ['reauth-required','attention-required','rate-limit-exceeded','timed-out','account-missing'];
function hasKnownStatus(account) {
  return KNOWN_STATUSES.includes(account.bank_sync_status);
}

Type guard

function isKnownSyncStatus(v) {
  return ['reauth-required','attention-required','rate-limit-exceeded','timed-out','account-missing'].includes(v);
}

Prevention

When it happens

Trigger: Calling getFailedSyncError with bank_sync_status undefined or set to any unrecognized string (anything other than reauth-required, attention-required, rate-limit-exceeded, timed-out, account-missing), typically an unknown/failed status stored after a sync failure.

Common situations: Schema or version drift between server-side status values and this client switch; corrupted or legacy account rows; miscellaneous sync failures (provider 500s, parsing errors).

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/9a5d3f941e124559. Report an issue: GitHub.