Budibase/budibase · error

Cannot store document without _id field.

Error message

Cannot store document without _id field.

What it means

put() in DatabaseImpl requires every stored document to carry an _id field; calling put with an _id-less document throws immediately. Documents must be created without a caller-chosen id via post(), which generates one. Timestamps (createdAt/updatedAt) are also stamped here before persistence.

Source

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

    }
    if (errorFound) {
      throw new CouchDBError(errorMessage, {
        name: this.name,
        status: 400,
      })
    }
  }

  async post(document: AnyDocument, opts?: DatabasePutOpts) {
    if (!document._id) {
      document._id = newid()
    }
    return this.put(document, opts)
  }

  async put(document: AnyDocument, opts?: DatabasePutOpts) {
    if (!document._id) {
      throw new Error("Cannot store document without _id field.")
    }
    return this.performCallWithDBCreation(async db => {
      if (!document.createdAt) {
        document.createdAt = new Date().toISOString()
      }
      document.updatedAt = new Date().toISOString()
      if (opts?.force && document._id) {
        try {
          const existing = await this.get(document._id)
          if (existing) {
            document._rev = existing._rev
          }
        } catch (err: any) {
          if (err.status !== 404) {
            throw err
          }
        }
      }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Use db.post(doc) instead of put when creating a new document without an id
  2. Ensure the document object includes _id before calling put (e.g. from a fetched row)
  3. Add a validation/normalization step that rejects or rejects-with-default _id payloads
  4. If an id should be derived, set it explicitly: doc._id = doc._id ?? generateId()

Example fix

// before
await db.put({ name: "row1" })
// after
await db.post({ name: "row1" }) // or await db.put({ ...doc, _id: doc._id ?? newid() })
Defensive patterns

Strategy: validation

Validate before calling

if (!doc._id) throw new Error("Document requires _id before put(); use post() to create")

Type guard

function hasId(doc: Record<string, unknown>): doc is Record<string, unknown> & { _id: string } {
  return typeof doc._id === "string" && doc._id.length > 0
}

Prevention

When it happens

Trigger: Calling db.put({...}) on an object lacking _id — e.g. building a doc from scratch, spreading a partial payload, or destructuring that drops the _id field.

Common situations: Mistakenly using put instead of post for new documents; constructing docs in migrations/scripts without copying _id; API payloads that omit _id; JSON.parse of a list that stripped the underscore-prefixed key.

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


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