actualbudget/actual · error

results.reason

Error message

results.reason

What it means

When fetching Pluggy.ai accounts, an error_code in the 'pluggyai-accounts' response is thrown with results.reason as the message. Note this branch does not fall back to the code itself, so an empty reason yields an empty error message.

Source

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

    }
  }, [
    dispatch,
    isEnableBankingSetupComplete,
    onEnableBankingInit,
    t,
    upgradingAccountId,
  ]);

  const onConnectPluggyAi = useCallback(async () => {
    if (!pluggyAiStatus.configured) {
      onPluggyAiInit();
      return;
    }

    try {
      const results = await send('pluggyai-accounts');
      if (results.error_code) {
        throw new Error(results.reason);
      }
      if ('error' in results) {
        throw new Error(results.error);
      }

      const externalAccounts = (results.accounts as PluggyAiAccount[]).map(
        oldAccount => ({
          account_id: oldAccount.id,
          name: `${oldAccount.name.trim()} - ${
            oldAccount.type === 'BANK' ? oldAccount.taxNumber : oldAccount.owner
          }`,
          institution: oldAccount.name,
          orgDomain: null,
          orgId: oldAccount.id,
          balance:
            oldAccount.type === 'BANK'
              ? oldAccount.bankData.automaticallyInvestedBalance +
                oldAccount.bankData.closingBalance

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Check results.reason (and server logs) for the Pluggy.ai failure cause
  2. Re-enter Pluggy.ai credentials via the provider settings so secret-set stores valid values
  3. Confirm the secret scope matches pluggyAiStatus.source (global vs per-budget-file)
  4. Verify network access from the sync server to api.pluggy.ai

Example fix

// before
if (results.error_code) {
  throw new Error(results.reason);
}
// after
if (results.error_code) {
  throw new Error(results.reason || results.error_code);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await send('pluggyai-accounts');
if (res.error_code) {
  throw new Error(res.reason || res.error_code);
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: The 'pluggyai-accounts' IPC returns { error_code: <non-null> } — e.g. invalid Pluggy.ai client id/secret, expired Pluggy auth, or the server failing to reach the Pluggy.ai API.

Common situations: Mis-typed pluggyai_clientId or pluggyai_clientSecret stored in secrets; per-budget-file vs global secret scope mismatch; Pluggy.ai API outage.

Related errors


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