Budibase/budibase · error · CouchDBError
CouchDB error: ${err.message}
Error message
CouchDB error: ${err.message} What it means
performCallWithDBCreation wraps write operations (put, bulkDocs). If CouchDB reports 404 'database_does_not_exist' it recreates the DB and retries once; any other failure is rethrown as CouchDBError('CouchDB error: ...') with safe properties preserved. This is the generic wrapper error for failed DB calls in the creation-aware path.
Source
Thrown at packages/backend-core/src/db/couch/DatabaseImpl.ts:189
}
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)
}
// stripping the error down the props which are safe/useful, drop everything else
throw new CouchDBError(`CouchDB error: ${err.message}`, err)
}
}
private async performCall<T>(call: DBCallback<T>): Promise<T> {
const db = this.getDb()
const fnc = await call(db)
try {
return await fnc()
} catch (err: any) {
// stripping the error down the props which are safe/useful, drop everything else
throw new CouchDBError(`CouchDB error: ${err.message}`, err)
}
}
async get<T extends Document>(id?: string): Promise<T> {
return this.performCall(db => {
if (!id) {
throw new Error("Unable to get doc without a valid _id.")View on GitHub (pinned to a81a902e9a)
Solutions
- Read the wrapped cause (err.getStatusCode/cause) to find the root CouchDB status and fix accordingly
- For 409 conflicts, fetch the latest rev and retry the write
- Verify CouchDB connectivity/credentials and disk space
- Implement bounded retry with backoff for transient network errors
Example fix
// before
await db.put(doc) // throws on stale rev
// after
try {
await db.put(doc)
} catch (e) {
if (e.statusCode === 409) {
const existing = await db.get(doc._id)
await db.put({ ...doc, _rev: existing._rev })
} else throw e
} Defensive patterns
Strategy: retry
Try / catch
try {
await db.put(doc)
} catch (err) {
if (err instanceof CouchDBError && err.statusCode === 409) {
// resolve conflict: refetch rev and retry
} else if (err instanceof CouchDBError && err.statusCode === 404) {
// db recreate already handled; surface to user
} else throw err
} Prevention
- Always write docs with a current _rev for updates
- Add bounded retry with backoff for transient network errors
- Monitor CouchDB health/disk; most non-404 failures are server-side
When it happens
Trigger: Any put/bulkDocs failing for reasons other than missing DB: document validation conflicts (409), quota exceeded (413), CouchDB unreachable (ECONNREFUSED), auth failure (401), or repeated 404 after recreate retry also fails.
Common situations: Writing docs with bad/missing _rev (conflict), CouchDB restarts mid-deploy, full disk, proxy timeouts, invalid doc IDs (must be strings, not starting _ except design docs).
Related errors
- DB does not exist
- Escalation ${escalationId} not found
- Unable to retrieve user list
- ${err.message}
- Unable to get bulk documents: ${missingIds}
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/cb496a68f89c7b8f.
Report an issue: GitHub.