actualbudget/actual · error

results.reason || results.error_code

Error message

results.reason || results.error_code

What it means

When fetching SimpleFin accounts, any server response carrying an error_code (other than the specially handled INVALID_ACCESS_TOKEN) is converted to a thrown Error whose message is the human-readable reason or the raw error code. This surfaces server-side SimpleFin failures to the bank-sync UI.

Source

Thrown at packages/desktop-client/src/components/banksync/useBuiltInBankSyncProviders.ts:411

    if (!isSimpleFinSetupComplete) {
      onSimpleFinInit();
      return;
    }

    if (loadingSimpleFinAccounts) {
      return;
    }

    setLoadingSimpleFinAccounts(true);

    try {
      const results = await send('simplefin-accounts');
      if (results.error_code === 'INVALID_ACCESS_TOKEN') {
        onSimpleFinInit();
        return;
      }
      if (results.error_code) {
        throw new Error(results.reason || results.error_code);
      }
      if ('error' in results && results.error) {
        throw new Error(results.reason || results.error);
      }

      const externalAccounts: SyncServerSimpleFinAccount[] = (
        (results.accounts ?? []) as SimpleFinAccount[]
      ).map(oldAccount => ({
        account_id: oldAccount.id,
        name: oldAccount.name,
        institution: oldAccount.org.name,
        orgDomain: oldAccount.org.domain,
        orgId: oldAccount.org.id,
        balance: oldAccount.balance,
      }));

      dispatch(
        pushModal({

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Read results.reason in the thrown message to identify the SimpleFin failure; fix the underlying cause
  2. Re-authenticate SimpleFin: get a fresh access token from your SimpleFin bridge and update settings
  3. If INVALID_ACCESS_TOKEN, use the handled re-init flow (onSimpleFinInit) to re-enter credentials
  4. Check sync-server logs and network connectivity to the SimpleFin bridge
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await send('simplefin-accounts');
if (res.error_code === 'INVALID_ACCESS_TOKEN') { reinitSimpleFin(); }
else if (res.error_code || ('error' in res && res.error)) {
  throw new Error(res.reason || res.error_code || res.error);
}

Type guard

const isSimpleFinError = (r: object): r is { error_code?: string; reason?: string; error?: string } =>
  'error_code' in r || 'error' in r;

Try / catch

try {
  await loadSimpleFinAccounts();
} catch (e) {
  notify(`SimpleFin failed: ${e instanceof Error ? e.message : String(e)}`);
}

Prevention

When it happens

Trigger: The 'simplefin-accounts' IPC returns { error_code: <something not INVALID_ACCESS_TOKEN> } — e.g. the SimpleFin bridge URL is invalid, the server cannot reach SimpleFin, or the access-nature token is rejected in a non-token-expiry way.

Common situations: Expired or revoked SimpleFin access token pasted into settings; wrong SimpleFin bridge URL; SimpleFin API outage or network failure from the sync server.

Related errors


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