Budibase/budibase · error · HTTPError

Project package contains a doc without an id.

Error message

Project package contains a doc without an id.

What it means

validateDocMatchesPath checks each imported doc parsed from the package. If the parsed JSON document has no `_id` field, this HTTPError (400) is thrown — every doc in a project package must be a persisted Budibase document with an id.

Source

Thrown at packages/server/src/sdk/workspace/projects/backups/imports.ts:341

const RESOURCE_ID_PREFIXES: Record<ResourceType, string[]> = {
  [ResourceType.PROJECT]: [prefixed(DocumentType.PROJECT)],
  [ResourceType.AGENT]: [prefixed(DocumentType.AGENT)],
  [ResourceType.DATASOURCE]: [
    prefixed(DocumentType.DATASOURCE),
    prefixed(DocumentType.DATASOURCE_PLUS),
  ],
  [ResourceType.TABLE]: [prefixed(DocumentType.TABLE)],
  [ResourceType.ROW_ACTION]: [prefixed(DocumentType.ROW_ACTIONS)],
  [ResourceType.QUERY]: [prefixed(DocumentType.QUERY)],
  [ResourceType.AUTOMATION]: [prefixed(DocumentType.AUTOMATION)],
  [ResourceType.WORKSPACE_APP]: [prefixed(DocumentType.WORKSPACE_APP)],
  [ResourceType.SCREEN]: [prefixed(DocumentType.SCREEN)],
}

const validateDocMatchesPath = (importedDoc: ImportedDoc) => {
  const id = importedDoc.doc._id
  if (!id) {
    throw new HTTPError("Project package contains a doc without an id.", 400)
  }

  const expectedFileName = `${id}.json`
  if (basename(importedDoc.path) !== expectedFileName) {
    throw new HTTPError(`Project package doc path does not match '${id}'.`, 400)
  }

  const validPrefixes = RESOURCE_ID_PREFIXES[importedDoc.resourceType]
  if (!validPrefixes.some(prefix => id.startsWith(prefix))) {
    throw new HTTPError(
      `Project package doc '${id}' does not match resource type '${importedDoc.resourceType}'.`,
      400
    )
  }
}

const remapObjectKeys = <T>(
  value: Record<string, T>,

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Open the offending .json in the archive and ensure it contains a valid `_id` field (matching its filename, e.g. `ta_abc123.json` → `_id: "ta_abc123"`).
  2. Re-export the project from Budibase instead of hand-assembling docs.
  3. Remove any non-document JSON files from the docs directory.
  4. Validate all docs before packaging: every file must be an object with `_id`, and filename must equal `${_id}.json`.

Example fix

// before: ta_abc123.json
{ "name": "My Table", "type": "table" }
// after
{ "_id": "ta_abc123", "name": "My Table", "type": "table" }
Defensive patterns

Strategy: type-guard

Validate before calling

import { readFileSync, readdirSync } from "fs"
import { join, basename } from "path"

function allDocsHaveIds(docsDir: string): boolean {
  for (const f of readdirSync(docsDir, { recursive: true })) {
    if (!String(f).endsWith(".json")) continue
    const doc = JSON.parse(readFileSync(join(docsDir, String(f)), "utf8"))
    if (typeof doc?._id !== "string" || doc._id.length === 0) return false
  }
  return true
}

Type guard

interface BudibaseDoc { _id: string }

function isDocWithId(value: unknown): value is BudibaseDoc {
  return (
    typeof value === "object" && value !== null && !Array.isArray(value) &&
    typeof (value as { _id?: unknown })._id === "string"
  )
}

Try / catch

try {
  await api.importProjectPackage(file)
} catch (err) {
  if (err?.status === 400 && err.message === "Project package contains a doc without an id.") {
    // find the .json missing _id and add it or remove the file
  } else throw err
}

Prevention

When it happens

Trigger: A .json file in the docs directory whose parsed object lacks `_id` — e.g. hand-authored config files, schema-only files, null/empty JSON, or an array root instead of a doc object placed in the docs tree.

Common situations: Manually editing package JSON and deleting the _id; tools exporting partial docs without ids; placing arbitrary config JSON (e.g. datasource settings snippets) into the docs directory; corrupted export where doc fields were dropped.

Related errors


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