Budibase/budibase · error · HTTPError
Project revision is required.
Error message
Project revision is required.
What it means
update() requires the current CouchDB _rev for optimistic concurrency; a missing _rev throws this 400 HTTPError. Without a revision the DB put could silently overwrite concurrent changes, so it is mandatory.
Source
Thrown at packages/server/src/sdk/workspace/projects/crud.ts:98
{
...project,
color: normaliseProjectColor(project.color),
_id: docIds.generateProjectID(),
createdAt: now,
updatedAt: now,
},
{ returnDoc: true }
)
return response.doc
}
export async function update(project: UpdateProjectInput): Promise<Project> {
if (!project._id) {
throw new HTTPError("Project id is required.", 400)
}
if (!project._rev) {
throw new HTTPError("Project revision is required.", 400)
}
if (Object.hasOwn(project, "name")) {
validateProjectName(project.name)
}
const db = context.getWorkspaceDB()
const persisted = await get(project._id)
if (!persisted) {
throw new HTTPError(`Project with id '${project._id}' not found.`, 404)
}
const response = await db.put(
{
...persisted,
...project,
...(Object.hasOwn(project, "color")
? { color: normaliseProjectColor(project.color) }
: {}),View on GitHub (pinned to a81a902e9a)
Solutions
- Pass the _rev from the last fetched version of the project
- Re-fetch the project to get a fresh _rev before updating
- Fix payload serialisation so underscore-prefixed fields survive (whitelist rather than blacklist)
- After a 409/conflict, re-fetch and retry with the new _rev
Example fix
// before
await sdk.projects.update({ _id: id, name: "New" })
// after
const project = await sdk.projects.get(id)
await sdk.projects.update({ _id: id, _rev: project!._rev, name: "New" }) Defensive patterns
Strategy: validation
Validate before calling
const hasRev = (p: { _rev?: string }): p is { _rev: string } =>
typeof p._rev === "string" && p._rev.length > 0
if (!hasRev(payload)) throw new Error("Missing project _rev")
await sdk.projects.update(payload) Type guard
const hasRev = (p: { _rev?: string }): p is { _rev: string } =>
typeof p._rev === "string" && p._rev.length > 0 Try / catch
try {
await sdk.projects.update(payload as { _id: string; _rev: string })
} catch (e) {
if (String(e.message).includes("revision is required")) {
const fresh = await sdk.projects.get(payload._id)
if (fresh) await sdk.projects.update({ ...payload, _rev: fresh._rev })
}
} Prevention
- Preserve underscore-prefixed fields through your serializers
- Always spread a freshly fetched project into update payloads
- After conflicts, re-fetch to obtain a new _rev rather than reusing old ones
When it happens
Trigger: Calling update with _id but no _rev — e.g. submitting a form payload that stripped underscore-prefixed fields, or constructing a fresh object with only the changed fields.
Common situations: Serializers/frameworks dropping _rev because of the leading underscore; clients caching a project without its revision; hand-built payloads from JSON that omitted _rev.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Revision is required for updates
- Project id is required.
- Invalid bookmark query
- Invalid limit query
- Limit query must be between 1 and 100
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/7b76704e56b0a09e.
Report an issue: GitHub.