Budibase/budibase · error · HTTPError

OAuth2 config with id '${configId}' not found.

Error message

OAuth2 config with id '${configId}' not found.

What it means

remove(configId, _rev) deletes the OAuth2 config document directly from the workspace DB. CouchDB/PouchDB throws a status-404 conflict when the document (id+rev) does not exist, and the catch block converts that into this 404 HTTPError so callers get a consistent error. Any other DB error is rethrown unchanged.

Source

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

      config.clientSecret === PASSWORD_REPLACEMENT
        ? existing.clientSecret
        : config.clientSecret,
  }

  const result = await db.put(toUpdate)

  await cleanCache(config._id)

  return { ...toUpdate, _rev: result.rev }
}

export async function remove(configId: string, _rev: string): Promise<void> {
  const db = context.getWorkspaceDB()
  try {
    await db.remove(configId, _rev)
  } catch (e: any) {
    if (e.status === 404) {
      throw new HTTPError(`OAuth2 config with id '${configId}' not found.`, 404)
    }
    throw e
  }

  await cleanCache(configId)

  const usageLog = await db.tryGet(docIds.generateOAuth2LogID(configId))
  if (usageLog) {
    await db.remove(usageLog)
  }
}

async function cleanCache(configId: string) {
  await cache.destroy(cache.CacheKey.OAUTH2_TOKEN(configId))
}

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Check the config still exists (fetch()/get()) before removing, or treat 404 as success in idempotent flows
  2. Re-fetch the config to obtain a fresh _rev and retry the remove
  3. Confirm the id belongs to the current workspace
  4. Clean up stale UI state that re-issues deletes

Example fix

// before
await sdk.workspace.oauth2.remove(config._id, config._rev)
// after
try {
  await sdk.workspace.oauth2.remove(config._id, config._rev)
} catch (e) {
  if (e.status !== 404) throw e // already deleted — treat as success
}
Defensive patterns

Strategy: try-catch

Validate before calling

const existing = await sdk.workspace.oauth2.get(configId)
if (!existing) return // already deleted; nothing to do

Type guard

function isNotFound(e: unknown): e is HTTPError {
  return e instanceof HTTPError && e.status === 404
}

Try / catch

try {
  await sdk.workspace.oauth2.remove(configId, rev)
} catch (e) {
  if (e instanceof HTTPError && e.status === 404) return // idempotent success
  throw e
}

Prevention

When it happens

Trigger: Calling remove() with a configId that was already deleted, an id that never existed, an outdated _rev (document changed/deleted since read), or an id from a different workspace DB.

Common situations: Double-clicking a delete button so the second request hits an already-deleted doc; stale revision after concurrent edit; idempotent retry logic re-running a delete.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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