Budibase/budibase · error · Error

OAuth2 auth config not found

Error message

OAuth2 auth config not found

What it means

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.

Source

Thrown at packages/server/src/automations/email/utils/getClient.ts:42

  datasourceId: string,
  authConfigId: string
) => {
  if (datasourceId !== authConfigId) {
    let datasource: Awaited<ReturnType<typeof sdk.datasources.get>>
    try {
      datasource = await sdk.datasources.get(datasourceId)
    } catch {
      // Not a REST datasource — fall through to legacy OAuth2 lookup
      return getLegacyOAuth2AccessToken(authConfigId)
    }

    const oauth2Config = datasource.config?.authConfigs?.find(
      (config: RestAuthConfig) =>
        config._id === authConfigId && config.type === RestAuthType.OAUTH2
    ) as OAuth2RestAuthConfig | undefined

    if (!oauth2Config) {
      throw new Error("OAuth2 auth config not found")
    }

    const token = await getTokenFromConfig(
      `${datasourceId}:${authConfigId}`,
      oauth2Config
    )
    return stripBearerPrefix(token)
  }

  return getLegacyOAuth2AccessToken(authConfigId)
}

const resolveOAuth2Ids = (inputs: EmailTriggerInputs) => {
  if (inputs.datasourceId && inputs.authConfigId) {
    return {
      datasourceId: inputs.datasourceId,
      authConfigId: inputs.authConfigId,
    }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Open the REST datasource and re-add/verify the OAuth2 auth config, then confirm the query references it.
  2. Check the authConfigId used by the query matches a config _id in datasource.config.authConfigs.
  3. Ensure the config's type is OAUTH2 (not basic/bearer).
  4. Re-save the datasource and query so the config binding is refreshed.

Example fix

// before
datasource.config = { authConfigs: [{ _id: "auth_1", type: RestAuthType.BASIC }] }
// query authConfigId: auth_oauth
// after
datasource.config = { authConfigs: [{ _id: "auth_oauth", type: RestAuthType.OAUTH2, clientId: "...", clientSecret: "..." }] }
Defensive patterns

Strategy: validation

Validate before calling

const cfg = datasource.config?.authConfigs?.find(c => c._id === authConfigId && c.type === RestAuthType.OAUTH2)
if (!cfg) throw new Error(`OAuth2 auth config ${authConfigId} missing from datasource ${datasourceId}`)

Type guard

const hasOAuth2Config = (ds: Datasource, id: string): boolean =>
  Boolean(ds.config?.authConfigs?.some(c => c._id === id && c.type === RestAuthType.OAUTH2))

Try / catch

try {
  token = await getOAuth2AccessToken(datasourceId, authConfigId)
} catch (e) {
  if (e.message === "OAuth2 auth config not found") {
    // re-open datasource config and rebind the query's auth config
  } else throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: Datasource auth configs edited/removed while queries still reference them; apps imported/exported losing auth config docs; authConfigId mismatch after duplicating datasources.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/13c127e6a3782d9c. Report an issue: GitHub.