Budibase/budibase · error · HTTPError

Project import failed while saving '${failedId}'.

Error message

Project import failed while saving '${failedId}'.

What it means

This error is thrown at the end of a project import when at least one document read from the exported package failed to save into the target database. The import loop records the _id of the first doc whose save returned an error, a missing id, or a missing rev, then aborts the whole import with an HTTP 400 naming that doc. It means the package parsed fine but persistence of one or more docs failed.

Source

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

  }>

  let failedId: string | undefined

  response.forEach((result, index) => {
    if (result.id && result.rev) {
      insertedDocs.push({
        _id: result.id,
        _rev: result.rev,
      })
    }

    if (!failedId && (result.error || !result.id || !result.rev)) {
      failedId = docs[index]._id
    }
  })

  if (failedId) {
    throw new HTTPError(
      `Project import failed while saving '${failedId}'.`,
      400
    )
  }
}

async function extractProjectPackage(
  file: { path: string },
  encryptPassword?: string
): Promise<ExtractedProjectPackage> {
  const fileStats = await fsp.stat(file.path)
  if (fileStats.size > MAX_ARCHIVE_SIZE_BYTES) {
    throw new HTTPError("Project package is too large.", 400)
  }
  if (encryptPassword && encryptPassword.length > MAX_ENCRYPT_PASSWORD_LENGTH) {
    throw new HTTPError("Project package password is too long.", 400)
  }

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Inspect the failedId named in the message in the extracted package and fix or remove the offending document
  2. Re-export the package from a source workspace on the same (or compatible) Budibase version instead of hand-editing files
  3. Check CouchDB health, disk space and write quota on the target environment and retry
  4. Retry the import; if a doc conflicts, delete the conflicting doc in the target or import into a fresh workspace

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-import: ensure the package is a valid tarball and target DB is healthy
const stats = await fsp.stat(packagePath)
if (stats.size === 0) throw new Error('package is empty')
const health = await fetch(`${couchDbUrl}/_up`)
if (!health.ok) throw new Error('target database not healthy')

Type guard

function hasSaveResultIdRev(r: { error?: unknown; id?: unknown; rev?: unknown }): r is { error?: undefined; id: string; rev: string } {
  return !r.error && typeof r.id === 'string' && r.id.length > 0 && typeof r.rev === 'string' && r.rev.length > 0
}

Try / catch

try {
  await importProjectPackage(file)
} catch (err) {
  if (err instanceof HTTPError && err.status === 400 && err.message.includes('import failed while saving')) {
    const failedId = err.message.match(/'(.+)'/)?.[1]
    // inspect/repair the failing doc or retry against a fresh workspace
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: Calling the project import API (POST import of a project package tarball) where one doc's save result has error set, or no _id/_rev, in the loop at imports.ts:905; the thrown message names failedId (the first failing doc's _id).

Common situations: Corrupt or hand-edited package contents producing docs the DB rejects; CouchDB write failures (conflicts, disk full, quota); importing an export from an incompatible Budibase version whose doc shapes no longer validate; interrupted/partial packages.

Related errors


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