{"record":{"id":"13c127e6a3782d9c","repo":"Budibase/budibase","slug":"oauth2-auth-config-not-found","errorCode":null,"errorMessage":"OAuth2 auth config not found","messagePattern":"OAuth2 auth config not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/automations/email/utils/getClient.ts","lineNumber":42,"sourceCode":"  datasourceId: string,\n  authConfigId: string\n) => {\n  if (datasourceId !== authConfigId) {\n    let datasource: Awaited<ReturnType<typeof sdk.datasources.get>>\n    try {\n      datasource = await sdk.datasources.get(datasourceId)\n    } catch {\n      // Not a REST datasource — fall through to legacy OAuth2 lookup\n      return getLegacyOAuth2AccessToken(authConfigId)\n    }\n\n    const oauth2Config = datasource.config?.authConfigs?.find(\n      (config: RestAuthConfig) =>\n        config._id === authConfigId && config.type === RestAuthType.OAUTH2\n    ) as OAuth2RestAuthConfig | undefined\n\n    if (!oauth2Config) {\n      throw new Error(\"OAuth2 auth config not found\")\n    }\n\n    const token = await getTokenFromConfig(\n      `${datasourceId}:${authConfigId}`,\n      oauth2Config\n    )\n    return stripBearerPrefix(token)\n  }\n\n  return getLegacyOAuth2AccessToken(authConfigId)\n}\n\nconst resolveOAuth2Ids = (inputs: EmailTriggerInputs) => {\n  if (inputs.datasourceId && inputs.authConfigId) {\n    return {\n      datasourceId: inputs.datasourceId,\n      authConfigId: inputs.authConfigId,\n    }","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/automations/email/utils/getClient.ts#L24-L60","documentation":"getOAuth2AccessToken looks up the REST datasource's authConfigs for a config matching the given authConfigId with type OAUTH2. If none is found (or the cast yields undefined), an Error is thrown because no OAuth2 token can be fetched for the request.","triggerScenarios":"A REST query/automation uses an OAuth2 authConfigId that is absent from datasource.config.authConfigs, or the config exists with a different type (e.g. BASIC), or the auth config was deleted from the datasource.","commonSituations":"Datasource auth configs edited/removed while queries still reference them; apps imported/exported losing auth config docs; authConfigId mismatch after duplicating datasources.","solutions":["Open the REST datasource and re-add/verify the OAuth2 auth config, then confirm the query references it.","Check the authConfigId used by the query matches a config _id in datasource.config.authConfigs.","Ensure the config's type is OAUTH2 (not basic/bearer).","Re-save the datasource and query so the config binding is refreshed."],"exampleFix":"// before\ndatasource.config = { authConfigs: [{ _id: \"auth_1\", type: RestAuthType.BASIC }] }\n// query authConfigId: auth_oauth\n// after\ndatasource.config = { authConfigs: [{ _id: \"auth_oauth\", type: RestAuthType.OAUTH2, clientId: \"...\", clientSecret: \"...\" }] }","handlingStrategy":"validation","validationCode":"const cfg = datasource.config?.authConfigs?.find(c => c._id === authConfigId && c.type === RestAuthType.OAUTH2)\nif (!cfg) throw new Error(`OAuth2 auth config ${authConfigId} missing from datasource ${datasourceId}`)","typeGuard":"const hasOAuth2Config = (ds: Datasource, id: string): boolean =>\n  Boolean(ds.config?.authConfigs?.some(c => c._id === id && c.type === RestAuthType.OAUTH2))","tryCatchPattern":"try {\n  token = await getOAuth2AccessToken(datasourceId, authConfigId)\n} catch (e) {\n  if (e.message === \"OAuth2 auth config not found\") {\n    // re-open datasource config and rebind the query's auth config\n  } else throw e\n}","preventionTips":["Re-check query auth bindings after editing datasource auth configs.","Include auth configs in app exports/backups where secrets policy allows (or re-create them on import).","Avoid deleting auth configs that queries still reference; audit first.","Keep authConfigId references stable when duplicating datasources."],"tags":["oauth2","rest-datasource","automation","configuration"],"backgroundTag":"missing-auth-config","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}