Budibase/budibase · error · CouchDBError

${err.message}

Error message

${err.message}

What it means

When the DB does not exist and auto-create is enabled, checkAndCreateDb calls nano.db.create. Any creation failure other than the benign 412 'already exists' race is rethrown as a CouchDBError carrying the original message. It surfaces underlying CouchDB failures (auth, connectivity, naming) during DB provisioning.

Source

Thrown at packages/backend-core/src/db/couch/DatabaseImpl.ts:168

  private getDb() {
    return this.nano().db.use(this.name)
  }

  private async checkAndCreateDb() {
    let shouldCreate = !this.pouchOpts?.skip_setup
    // check exists in a lightweight fashion
    let exists = await this.exists()
    if (!shouldCreate && !exists) {
      throw new Error("DB does not exist")
    }
    if (!exists) {
      try {
        await this.nano().db.create(this.name)
      } catch (err: any) {
        // Handling race conditions
        if (err.statusCode !== 412) {
          throw new CouchDBError(err.message, err)
        }
      }
    }
    return this.getDb()
  }

  // this function fetches the DB and handles if DB creation is needed
  private async performCallWithDBCreation<T>(
    call: DBCallback<T>
  ): Promise<any> {
    const db = this.getDb()
    const fnc = await call(db)
    try {
      return await fnc()
    } catch (err: any) {
      if (err.statusCode === 404 && err.reason === DATABASE_NOT_FOUND) {
        await this.checkAndCreateDb()
        return await this.performCallWithDBCreation(call)

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Verify CouchDB credentials and URL env vars (COUCH_DB_URL, user, password)
  2. Validate the DB name (must be lowercase, /^[a-z][a-z0-9_$()+-]*$/)
  3. Check CouchDB availability/health and disk space; fix server-side issue then retry
  4. Inspect the wrapped err passed to CouchDBError for the root statusCode/reason

Example fix

// before
try { await db.put(doc) } catch (e) { /* opaque CouchDBError */ }
// after
try { await db.put(doc) } catch (e) {
  if (e.statusCode === 412) { /* already exists - ignore */ }
  else throw e
}
Defensive patterns

Strategy: retry

Validate before calling

const validName = /^[a-z][a-z0-9_$()+-]*$/.test(dbName)
if (!validName) throw new Error(`Invalid CouchDB name: ${dbName}`)

Try / catch

try {
  await db.put(doc)
} catch (err) {
  if (err instanceof CouchDBError && err.statusCode === 412) {
    // DB already exists - safe to continue
  } else throw err
}

Prevention

When it happens

Trigger: Auto-creating a DB while CouchDB returns an error: admin party disabled and missing credentials (401), connection refused, invalid DB name (400, illegal characters/case), or out-of-disk/quota server errors — anything with statusCode !== 412.

Common situations: Wrong COUCH_DB_URL/user/password env vars, DB names containing uppercase or invalid chars, CouchDB restarted or unreachable, race where two nodes create and one hits a non-412 error (e.g. 401/500).

Related errors


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