{"record":{"id":"b788ceeca520f934","repo":"actualbudget/actual","slug":"timed-out-b788ce","errorCode":"TIMED_OUT","errorMessage":"TIMED_OUT","messagePattern":"TIMED_OUT","errorType":"error_code","errorClass":"BankSyncError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/accounts/sync.ts","lineNumber":216,"sourceCode":"  logger.log('Pulling transactions from SimpleFin');\n\n  let res;\n  try {\n    res = await post(\n      getServer().SIMPLEFIN_SERVER + '/transactions',\n      {\n        accountId: acctId,\n        startDate: since,\n      },\n      {\n        'X-ACTUAL-TOKEN': userToken,\n      },\n      // 5 minute timeout for batch sync, one minute for individual accounts\n      Array.isArray(acctId) ? 300000 : 60000,\n    );\n  } catch (error) {\n    logger.error('Suspected timeout during bank sync:', error);\n    throw BankSyncError('TIMED_OUT', 'TIMED_OUT');\n  }\n\n  if (Object.keys(res).length === 0) {\n    throw BankSyncError('NO_DATA', 'NO_DATA');\n  }\n  if (res.error_code) {\n    throw BankSyncError(res.error_type, res.error_code);\n  }\n\n  let retVal = {};\n  if (batchSync) {\n    const batchErrors = res.errors;\n    for (const accountId of Object.keys(res)) {\n      if (accountId === 'errors') continue;\n\n      const data = res[accountId];\n      const error = batchErrors?.[accountId]?.[0];\n","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/accounts/sync.ts#L198-L234","documentation":"downloadSimpleFinTransactions wraps its HTTP post in a try/catch with a 60s timeout for single-account syncs and 300s for batch syncs (sync.ts:211-217). Any failure of that request — including the configured timeout firing — is logged and rethrown as BankSyncError('TIMED_OUT', 'TIMED_OUT'). It indicates the SimpleFin server did not respond in time, not necessarily that the bank itself failed.","triggerScenarios":"SimpleFin /transactions call exceeding the 60000ms (single account) or 300000ms (batch array) timeout, or the post throwing a network error; occurs inside syncAccount via downloadSimpleFinTransactions.","commonSituations":"Slow bank aggregation on SimpleFin's side; very large batch syncs of many accounts; network issues between sync server and SimpleFin; self-hosted setups with slow DNS/proxy.","solutions":["Retry the sync — timeouts are often transient; consider syncing accounts in smaller batches to stay under the 300s batch limit.","Check connectivity from the sync server to the SimpleFin server URL (getServer().SIMPLEFIN_SERVER).","Reduce the number of accounts in a batch sync so the request completes within the timeout.","Verify the SimpleFin access URL/claims token is current; stale setup URLs cause slow failed lookups."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Keep batches small enough to finish within the 300s batch timeout:\nif (Array.isArray(acctIds) && acctIds.length > 25) {\n  throw new Error('Batch too large — split into smaller groups to avoid SimpleFin timeouts');\n}","typeGuard":"function isTimedOutError(e: unknown): boolean {\n  return typeof e === 'object' && e !== null &&\n    (e as { errorType?: string }).errorType === 'TIMED_OUT' &&\n    (e as { errorCode?: string }).errorCode === 'TIMED_OUT';\n}","tryCatchPattern":"try {\n  await syncAccount(accountId);\n} catch (e) {\n  if (isTimedOutError(e)) {\n    await delay(5000);\n    await syncAccount(accountId); // retry with backoff, smaller batch\n  } else throw e;\n}","preventionTips":["Retry with exponential backoff — SimpleFin aggregation can be transiently slow.","Split large batch syncs into per-account or small-group syncs.","Verify network/DNS from the sync server to SIMPLEFIN_SERVER.","Avoid overlapping scheduled syncs that contend for the same slow provider."],"tags":["bank-sync","simplefin","timeout","network"],"backgroundTag":"request-timeout","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}