{"record":{"id":"ee251e61930d6d3c","repo":"Budibase/budibase","slug":"project-import-failed-while-saving-failedid","errorCode":null,"errorMessage":"Project import failed while saving '${failedId}'.","messagePattern":"Project import failed while saving '(.+?)'\\.","errorType":"validation","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/projects/backups/imports.ts","lineNumber":905,"sourceCode":"  }>\n\n  let failedId: string | undefined\n\n  response.forEach((result, index) => {\n    if (result.id && result.rev) {\n      insertedDocs.push({\n        _id: result.id,\n        _rev: result.rev,\n      })\n    }\n\n    if (!failedId && (result.error || !result.id || !result.rev)) {\n      failedId = docs[index]._id\n    }\n  })\n\n  if (failedId) {\n    throw new HTTPError(\n      `Project import failed while saving '${failedId}'.`,\n      400\n    )\n  }\n}\n\nasync function extractProjectPackage(\n  file: { path: string },\n  encryptPassword?: string\n): Promise<ExtractedProjectPackage> {\n  const fileStats = await fsp.stat(file.path)\n  if (fileStats.size > MAX_ARCHIVE_SIZE_BYTES) {\n    throw new HTTPError(\"Project package is too large.\", 400)\n  }\n  if (encryptPassword && encryptPassword.length > MAX_ENCRYPT_PASSWORD_LENGTH) {\n    throw new HTTPError(\"Project package password is too long.\", 400)\n  }\n","sourceCodeStart":887,"sourceCodeEnd":923,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/backups/imports.ts#L887-L923","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Inspect the failedId named in the message in the extracted package and fix or remove the offending document","Re-export the package from a source workspace on the same (or compatible) Budibase version instead of hand-editing files","Check CouchDB health, disk space and write quota on the target environment and retry","Retry the import; if a doc conflicts, delete the conflicting doc in the target or import into a fresh workspace"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// pre-import: ensure the package is a valid tarball and target DB is healthy\nconst stats = await fsp.stat(packagePath)\nif (stats.size === 0) throw new Error('package is empty')\nconst health = await fetch(`${couchDbUrl}/_up`)\nif (!health.ok) throw new Error('target database not healthy')","typeGuard":"function hasSaveResultIdRev(r: { error?: unknown; id?: unknown; rev?: unknown }): r is { error?: undefined; id: string; rev: string } {\n  return !r.error && typeof r.id === 'string' && r.id.length > 0 && typeof r.rev === 'string' && r.rev.length > 0\n}","tryCatchPattern":"try {\n  await importProjectPackage(file)\n} catch (err) {\n  if (err instanceof HTTPError && err.status === 400 && err.message.includes('import failed while saving')) {\n    const failedId = err.message.match(/'(.+)'/)?.[1]\n    // inspect/repair the failing doc or retry against a fresh workspace\n  } else {\n    throw err\n  }\n}","preventionTips":["Never hand-edit documents inside an exported package; always re-export from the source workspace","Keep source and target Budibase versions compatible before importing","Monitor CouchDB disk space and quotas in target environments","Test imports against a staging workspace before production"],"tags":["import","database","http-400"],"backgroundTag":"project-import-doc-save-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}