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

  1. Ensure the query object comes from the store list or a full fetch so it includes _id and _rev
  2. Check that the code constructing the Query object copies _id and _rev (don't pick only known fields)
  3. If deleting a newly created query, save it first to obtain the CouchDB revision
  4. 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

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


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