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
- Check server/bank-sync logs for the underlying provider error
- Verify the server's bank_sync_status values match the cases handled in syncStatus.ts (version drift)
- Run a fresh manual sync and re-read the resulting status
- 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
- Keep server-side status enum and the client switch in sync (shared type)
- Log the unexpected bank_sync_status value when hitting the default branch
- Treat SYNC_ERROR as a signal to inspect provider logs, not to retry blindly
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
- response.reason || response.error_code
- response.reason || response.error || fallbackMessage
- Account with ID ${upgradingId} not found.
- Bank with ID ${bankId} not found.
- `payeeName` is required when adding a transaction
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/9a5d3f941e124559.
Report an issue: GitHub.