Budibase/budibase · error
Query ID or Revision is missing
Error message
Query ID or Revision is missing
What it means
The queries store's delete() method requires both the CouchDB document _id and _rev before it will call the delete API. If either is missing on the passed Query object it throws immediately, because a valid revision is needed for CouchDB to delete the document. This is a fail-fast guard to avoid sending a doomed request to the server.
Source
Thrown at packages/builder/src/stores/builder/queries.ts:163
...state,
selectedQueryId: id,
}))
}
async preview(query: QueryPreview): Promise<PreviewQueryResponse> {
const result = await API.previewQuery(query)
// Assume all the fields are strings and create a basic schema from the
// unique fields returned by the server
const schema: Record<string, QuerySchema> = {}
for (let [field, metadata] of Object.entries(result.schema)) {
schema[field] = (metadata as QuerySchema) || { type: "string" }
}
return { ...result, schema, rows: result.rows || [] }
}
async delete(query: Query) {
if (!query._id || !query._rev) {
throw new Error("Query ID or Revision is missing")
}
await API.deleteQuery(query._id, query._rev)
this.store.update(state => ({
...state,
list: state.list.filter(existing => existing._id !== query._id),
}))
skipUnsavedPromptIds.delete(query._id)
}
async duplicate(query: Query) {
let list = get(this.store).list
const newQuery = { ...query }
const datasourceId = query.datasourceId
delete newQuery._id
delete newQuery._rev
newQuery.name = duplicateName(
query.name,View on GitHub (pinned to a81a902e9a)
Solutions
- Ensure the query object comes from the store list or a full fetch so it includes _id and _rev
- Check that the code constructing the Query object copies _id and _rev (don't pick only known fields)
- If deleting a newly created query, save it first to obtain the CouchDB revision
- Log the query object before delete to confirm both fields are present
Example fix
// before
await queries.delete({ name: q.name } as Query)
// after
const full = get(queries).list.find(x => x._id === q._id)
await queries.delete(full) Defensive patterns
Strategy: validation
Validate before calling
const canDelete = (q: Query) => Boolean(q._id && q._rev)
if (!canDelete(query)) throw new Error("Query requires _id and _rev before delete") Type guard
const isDeletableQuery = (q: Query): q is Query & { _id: string; _rev: string } =>
typeof q._id === "string" && typeof q._rev === "string" Try / catch
try {
await queries.delete(query)
} catch (e) {
if (e.message.includes("ID or Revision is missing")) {
const full = get(queries).list.find(x => x._id === query._id)
if (full) await queries.delete(full)
} else throw e
} Prevention
- Always source query objects from the store list or full API fetches
- Avoid constructing Query objects manually from partial fields
- Never spread-and-strip internal CouchDB fields (_id, _rev) before delete
- Validate _id/_rev presence before invoking destructive operations
When it happens
Trigger: Calling store.queries.delete(query) with a query object that has no _id or no _rev — e.g. a newly constructed/in-memory query object, a query built from a template, or an object deserialized without the CouchDB metadata fields.
Common situations: Passing a draft query created before save; spreading a query into a new object and dropping internal fields; fetching query data from an endpoint that strips _rev; stale clients holding a partial query record.
Related errors
- Unable to remove doc without a valid _id and _rev.
- Cannot store document without _id field.
- Source table '${relationship.sourceTable}' not found in data
- Target table '${relationship.targetTable}' not found in data
- Invalid custom REST template
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/77a6fed455fcf39b.
Report an issue: GitHub.