{"record":{"id":"f70b5ea1413b2ce3","repo":"Budibase/budibase","slug":"error-getting-account-by-email-email","errorCode":null,"errorMessage":"Error getting account by email ${email}","messagePattern":"Error getting account by email (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/accounts/accounts.ts","lineNumber":33,"sourceCode":"\nexport const getAccount = async (\n  email: string\n): Promise<CloudAccount | undefined> => {\n  if (EXIT_EARLY) {\n    return\n  }\n  const payload = {\n    email,\n  }\n  const response = await api.post(`/api/accounts/search`, {\n    body: payload,\n    headers: {\n      [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,\n    },\n  })\n\n  if (response.status !== 200) {\n    throw new Error(`Error getting account by email ${email}`)\n  }\n\n  const json: CloudAccount[] = await response.json()\n  return json[0]\n}\n\nexport const getAccountByTenantId = async (\n  tenantId: string\n): Promise<CloudAccount | undefined> => {\n  if (EXIT_EARLY) {\n    return\n  }\n  const payload = {\n    tenantId,\n  }\n  const response = await api.post(`/api/accounts/search`, {\n    body: payload,\n    headers: {","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/accounts/accounts.ts#L15-L51","documentation":"fetchSharePointSitesByDatasourceAuthConfig lists SharePoint sites using an OAuth2 client-credentials bearer token. When the initial Graph /sites call returns 401, it clears the cached token and retries once; if the retry also returns 401, this HTTPError (400) is thrown. It means the tenant/client credentials themselves cannot authenticate to Microsoft Graph, not just a stale token.","triggerScenarios":"getSharePointBearerToken or fetchSharePointSitesByAppToken throws an error with status 401, cleanStoredTokensForAuthConfig runs, a fresh token is fetched, and the retried /sites?search=* call returns 401 again.","commonSituations":"Wrong clientSecret in the OAuth2 client-credentials auth config; app registration deleted or disabled; tenant ID / token URL pointing at the wrong tenant; client credentials flow disabled or app blocked by conditional access; expired client secret in Azure AD.","solutions":["Verify the client ID, client secret, and token URL in the datasource's OAuth2 client-credentials auth config against the Azure app registration.","In Azure Portal, confirm the app registration secret is not expired and the app is enabled in the correct tenant.","Confirm the app has SharePoint application permissions (Sites.Read.All or similar) and admin consent granted, then re-run the site listing.","Regenerate the client secret and update the auth config, then retry."],"exampleFix":"// before\n\"authConfig\": { \"method\": \"post\", \"url\": \"https://login.microsoftonline.com/old-tenant/oauth2/v2.0/token\", \"clientId\": \"old-id\", \"clientSecret\": \"expired-secret\", \"scope\": \"https://graph.microsoft.com/.default\" }\n// after\n\"authConfig\": { \"method\": \"post\", \"url\": \"https://login.microsoftonline.com/<correct-tenant-id>/oauth2/v2.0/token\", \"clientId\": \"<correct-client-id>\", \"clientSecret\": \"<newly-generated-secret>\", \"scope\": \"https://graph.microsoft.com/.default\" }","handlingStrategy":"try-catch","validationCode":"// Pre-check the auth config before calling\nconst config = datasource.config?.authConfigs?.find(c => c._id === authConfigId)\nif (!config?.clientId || !config?.clientSecret || !config?.url) {\n  throw new Error(\"SharePoint OAuth2 client credentials are incomplete\")\n}","typeGuard":null,"tryCatchPattern":"try {\n  await fetchSharePointSitesByDatasourceAuthConfig(datasourceId, authConfigId)\n} catch (e) {\n  if (String(e.message).includes(\"Authentication failed with Microsoft Graph\")) {\n    // surface a config-repair prompt: client ID/secret/tenant are wrong\n  } else throw e\n}","preventionTips":["Set calendar reminders for Azure AD client-secret expiry dates.","Test credentials with a direct token request (curl to the token URL) after any config change.","Keep admin consent granted for Sites.Read.All on the app registration.","Store tenant ID, client ID and secret in one reviewed place to avoid tenant mismatches."],"tags":["sharepoint","microsoft-graph","authentication","oauth2"],"backgroundTag":"oauth-client-authentication-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}