actualbudget/actual · error

Unrecognized bank-sync provider: ${acctRow.account_sync_sour

Error message

Unrecognized bank-sync provider: ${acctRow.account_sync_source}

What it means

Actual's bank sync dispatches on the account's account_sync_source column, supporting 'goCardless', 'simpleFin', and 'enableBanking'. If an account row carries any other value (or a stale/legacy source string from an older version), downloadFrom4 different providers is impossible, so sync.ts throws this Error naming the unrecognized provider.

Source

Thrown at packages/loot-core/src/server/accounts/sync.ts:1243

      acctId,
      syncStartDate,
      fileId,
    );
  } else if (acctRow.account_sync_source === 'akahu') {
    download = await downloadAkahuTransactions(acctId, syncStartDate);
  } else if (acctRow.account_sync_source === 'goCardless') {
    download = await downloadGoCardlessTransactions(
      userId,
      userKey,
      acctId,
      bankId,
      syncStartDate,
      newAccount,
    );
  } else if (acctRow.account_sync_source === 'enableBanking') {
    download = await downloadEnableBankingTransactions(acctId, syncStartDate);
  } else {
    throw new Error(
      `Unrecognized bank-sync provider: ${acctRow.account_sync_source}`,
    );
  }

  return processBankSyncDownload(
    download,
    id,
    acctRow,
    newAccount,
    customStartingBalance,
    customStartingDate,
  );
}

export async function simpleFinBatchSync(
  accounts: Array<Pick<AccountEntity, 'id' | 'account_id'>>,
) {
  const startDates = await Promise.all(

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Query the accounts table (SELECT id,name,account_sync_source FROM accounts) and fix the unsupported value to one of goCardless/simpleFin/enableBanking, or NULL it to unlink bank sync.
  2. If the account should no longer auto-sync, clear its bank-sync configuration in the UI (Edit account > remove bank-sync) so account_sync_source is reset.
  3. Update Actual to a version that supports the provider string stored on the account (or migrate the legacy identifier to the current one).
  4. Restore the accounts row from a backup taken before the value was corrupted.

Example fix

// before (sqlite)
SELECT id, account_sync_source FROM accounts; -- row shows 'plaid'
// after
UPDATE accounts SET account_sync_source = NULL WHERE id = '...'; -- unlink and reconfigure bank sync in the UI
Defensive patterns

Strategy: validation

Validate before calling

const VALID_SOURCES = ['goCardless', 'simpleFin', 'enableBanking'];
const acct = await db.get('SELECT account_sync_source FROM accounts WHERE id = ?', [accountId]);
if (acct.account_sync_source != null && !VALID_SOURCES.includes(acct.account_sync_source)) {
  throw new Error(`account ${acct.id} has invalid bank-sync source: ${acct.account_sync_source}`);
}

Type guard

function hasKnownSyncSource(acct) {
  return acct.account_sync_source == null ||
    ['goCardless', 'simpleFin', 'enableBanking'].includes(acct.account_sync_source);
}

Try / catch

try {
  await bankSync.syncAccount(accountId);
} catch (e) {
  if (e.message.startsWith('Unrecognized bank-sync provider')) {
    await unlinkBankSync(accountId); // reset account_sync_source and prompt user to reconfigure
  } else throw e;
}

Prevention

When it happens

Trigger: BankSync/Schedule/normal sync runs against an account whose acctRow.account_sync_source is set to a value outside the known set — e.g. data migrated from an older Actual version, a manually edited SQLite DB, or a third-party tool writing an unsupported source string.

Common situations: Upgrading from a version that used a different provider identifier; manually editing the accounts table; a forked/patched build adding a custom provider that the running core doesn't know; corrupted DB rows after a failed migration; copying a budget between deployments with different provider plugins.

Related errors


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