{"record":{"id":"53872aa030fdf3eb","repo":"actualbudget/actual","slug":"accountid-and-startdate-arrays-must-be-the-same-le","errorCode":null,"errorMessage":"accountId and startDate arrays must be the same length","messagePattern":"accountId and startDate arrays must be the same length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/sync-server/src/app-simplefin/app-simplefin.js","lineNumber":110,"sourceCode":"  handleError(async (req, res) => {\n    const { accountId, startDate } = req.body || {};\n\n    const accessKey = secretsService.get(SecretName.simplefin_accessKey);\n\n    if (isInvalidAccessKey(accessKey)) {\n      invalidToken(res);\n      return;\n    }\n\n    if (Array.isArray(accountId) !== Array.isArray(startDate)) {\n      console.log({ accountId, startDate });\n      throw new Error(\n        'accountId and startDate must either both be arrays or both be strings',\n      );\n    }\n    if (Array.isArray(accountId) && accountId.length !== startDate.length) {\n      console.log({ accountId, startDate });\n      throw new Error('accountId and startDate arrays must be the same length');\n    }\n\n    const earliestStartDate = Array.isArray(startDate)\n      ? startDate.reduce((a, b) => (a < b ? a : b))\n      : startDate;\n    let results;\n    try {\n      results = await getTransactions(\n        accessKey,\n        Array.isArray(accountId) ? accountId : [accountId],\n        new Date(earliestStartDate),\n      );\n    } catch (e) {\n      if (isForbidden(e.message)) {\n        invalidToken(res);\n      } else {\n        serverDown(e, res);\n      }","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/sync-server/src/app-simplefin/app-simplefin.js#L92-L128","documentation":"In batch mode, the SimpleFIN handler requires the accountId and startDate arrays to have the same length so each account can be paired with its own start date. When the lengths differ it throws 'accountId and startDate arrays must be the same length'. This prevents silently misaligning accounts to dates in the subsequent zip/reduce.","triggerScenarios":"Calling the SimpleFIN transactions endpoint with N account ids but M start dates where N !== M, e.g. adding a third account to the request but forgetting to add its start date.","commonSituations":"Dynamically building the batch payload and appending an account without the matching date; mapping over accounts but filtering some start dates; client caching an old date array after the account list changed.","solutions":["Ensure one start date per account, in the same order as the accountId array.","Rebuild the payload by mapping accounts to dates in a single pass so the arrays stay aligned.","If all accounts share a start date, either repeat it N times or use the single-string form only when calling with one account.","Assert equal lengths in the caller before sending the request."],"exampleFix":"// before\nconst payload = { accountId: accounts, startDate: dates.slice(0, 2) };\n\n// after\nif (accounts.length !== dates.length) throw new Error('accounts/dates length mismatch');\nconst payload = { accountId: accounts, startDate: accounts.map(a => startDateByAccount[a]) };","handlingStrategy":"validation","validationCode":"if (Array.isArray(accountId) && accountId.length !== startDate.length) {\n  throw new Error('accountId and startDate arrays must be the same length');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Construct batch payloads by mapping over accounts so dates can't drift out of alignment.","Assert equal lengths in integration tests for the batch endpoint.","Prefer a single source of truth (array of {accountId, startDate} pairs) flattened at call time."],"tags":["simplefin","validation","api-misuse"],"backgroundTag":"parameter-validation-failed","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}