{"record":{"id":"44de361e522384a0","repo":"actualbudget/actual","slug":"not-configured-44de36","errorCode":"not-configured","errorMessage":"Pluggy credentials are not configured","messagePattern":"Pluggy credentials are not configured","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"packages/sync-server/src/app-pluggyai/app-pluggyai.js","lineNumber":88,"sourceCode":"          details: 'invalid fileId',\n        });\n        return;\n      }\n\n      if (!canAccessFile(fileId, res.locals.user_id)) {\n        res.status(403).send({\n          status: 'error',\n          reason: 'file-access-denied',\n          details: \"You don't have permissions over this file\",\n        });\n        return;\n      }\n    }\n\n    try {\n      const source = pluggyaiService.getCredentialSource(fileId);\n      if (!source) {\n        res.status(400).send({\n          status: 'error',\n          reason: 'not-configured',\n          details: 'Pluggy credentials are not configured',\n        });\n        return;\n      }\n\n      const credentialFileId = source === 'per-budget-file' ? fileId : null;\n      const itemIds = (\n        secretsService.get(SecretName.pluggyai_itemIds, credentialFileId) ?? ''\n      )\n        .split(',')\n        .map(item => item.trim())\n        .filter(Boolean);\n\n      let accounts = [];\n\n      for (const item of itemIds) {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/sync-server/src/app-pluggyai/app-pluggyai.js#L70-L106","documentation":"For POST /status (or /accounts), after fileId checks the server calls pluggyaiService.getCredentialSource(fileId); when no Pluggy credential source is stored for that budget it returns HTTP 400 with reason 'not-configured' and details 'Pluggy credentials are not configured'. The Pluggy.ai integration requires per-budget stored credentials (client id/secret or source id) before it can query Pluggy.","triggerScenarios":"POST /status or /accounts with a valid, accessible fileId for which no Pluggy credentials have ever been saved via the integration's configuration endpoint.","commonSituations":"Fresh budget never configured for Pluggy; credentials cleared after a server reset/DB restore; testing endpoints before completing the Pluggy setup step; missing PLUGGY_AI_* env-based configuration.","solutions":["Configure Pluggy credentials for the budget via the integration's config endpoint (or the app UI) before calling /status","Set the required Pluggy environment variables on the sync-server (e.g. PLUGGY_CLIENT_ID/PLUGGY_CLIENT_SECRET) and restart it","Confirm the fileId used is the same budget where credentials were saved","Re-save credentials if a database restore dropped them"],"exampleFix":"// before\ncurl -X POST /pluggyai/status -H 'X-Actual-File-Id: <id>'  // 400 not-configured\n// after\ncurl -X POST /pluggyai/configure -d '{\"clientId\":\"...\",\"clientSecret\":\"...\"}' -H 'X-Actual-File-Id: <id>'\ncurl -X POST /pluggyai/status -H 'X-Actual-File-Id: <id>'","handlingStrategy":"fallback","validationCode":"// pre-check via /status before dependent calls; treat not-configured as setup-needed\nconst res = await fetch('/pluggyai/status', { headers: { 'X-Actual-File-Id': fileId, ...authHeaders } });\nconst body = await res.json();\nif (body.status === 'error' && body.reason === 'not-configured') {\n  throw new Error('Run Pluggy configuration for this budget first');\n}","typeGuard":null,"tryCatchPattern":"const res = await fetch('/pluggyai/accounts', { method: 'POST', headers, body });\nif (res.status === 400) {\n  const body = await res.json();\n  if (body.reason === 'not-configured') {\n    await configurePluggyCredentials(fileId, clientId, clientSecret);\n    return retry(); // single retry after configuration\n  }\n}","preventionTips":["Run configuration/setup as the first step of any Pluggy integration script","Persist credentials in env or config so restarts keep them","Re-verify config after DB restores","Use the same fileId for configure and query calls"],"tags":["pluggyai","http-400","missing-credentials","configuration"],"backgroundTag":"missing-credentials-configuration","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}