Budibase/budibase · error · HTTPError

OAuth2 config with name '${name}' is already taken.

Error message

OAuth2 config with name '${name}' is already taken.

What it means

guardName enforces unique OAuth2 config names within a workspace. Before create (no id) or update (id to exclude), it fetches all configs and throws HTTP 400 if another config with the same name exists under a different _id. Names are user-facing identifiers used to select configs, so duplicates are rejected.

Source

Thrown at packages/server/src/sdk/workspace/oauth2/crud.ts:23

  HTTPError,
  utils,
} from "@budibase/backend-core"
import {
  DocumentType,
  OAuth2Config,
  PASSWORD_REPLACEMENT,
  SEPARATOR,
  WithoutDocMetadata,
  WithRequired,
} from "@budibase/types"

type CreatedOAuthConfig = WithRequired<OAuth2Config, "_id" | "_rev">

async function guardName(name: string, id?: string) {
  const existingConfigs = await fetch()

  if (existingConfigs.find(c => c.name === name && c._id !== id)) {
    throw new HTTPError(
      `OAuth2 config with name '${name}' is already taken.`,
      400
    )
  }
}

export async function fetch(): Promise<CreatedOAuthConfig[]> {
  const db = context.getWorkspaceDB()
  const docs = await db.allDocs<OAuth2Config>(
    docIds.getOAuth2ConfigParams(null, { include_docs: true })
  )
  const result = docs.rows.map(r => ({
    ...r.doc!,
    _id: r.doc!._id!,
    _rev: r.doc!._rev!,
  }))
  return result
}

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Choose a unique name — fetch existing configs and pick an unused one
  2. If updating, ensure the update targets the existing config's own _id so guardName excludes it from the collision check
  3. If a duplicate was created concurrently, delete or rename one of the duplicates

Example fix

// before
await oauth2.create({ name: "acme", ... }) // name already exists -> 400
// after
const existing = await oauth2.fetch()
const name = existing.some(c => c.name === "acme") ? "acme-2" : "acme"
await oauth2.create({ name, ... })
Defensive patterns

Strategy: validation

Validate before calling

const configs = await oauth2.fetch()
if (configs.some(c => c.name === desiredName && c._id !== updatingId)) {
  throw new Error(`Name '${desiredName}' is already taken — choose another`)

Try / catch

try {
  await oauth2.create(config)
} catch (err) {
  if (err instanceof HTTPError && err.status === 400 && /already taken/.test(err.message)) {
    const uniqueName = `${config.name}-${Date.now()}`
    return oauth2.create({ ...config, name: uniqueName })
  }
  throw err
}

Prevention

When it happens

Trigger: Creating a new OAuth2 config whose name collides with an existing one, or renaming a config via update to a name already held by a different config — guardName excludes only the config being updated (matching _id).

Common situations: Two users creating configs with the same provider name concurrently; renaming a config to match a sibling; automation/scripts re-running creates without idempotency checks.

Related errors


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