{"record":{"id":"ae64f4b00562b8b0","repo":"Budibase/budibase","slug":"project-package-doc-path-does-not-match-id","errorCode":null,"errorMessage":"Project package doc path does not match '${id}'.","messagePattern":"Project package doc path does not match '(.+?)'\\.","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/projects/backups/imports.ts","lineNumber":346,"sourceCode":"    prefixed(DocumentType.DATASOURCE_PLUS),\n  ],\n  [ResourceType.TABLE]: [prefixed(DocumentType.TABLE)],\n  [ResourceType.ROW_ACTION]: [prefixed(DocumentType.ROW_ACTIONS)],\n  [ResourceType.QUERY]: [prefixed(DocumentType.QUERY)],\n  [ResourceType.AUTOMATION]: [prefixed(DocumentType.AUTOMATION)],\n  [ResourceType.WORKSPACE_APP]: [prefixed(DocumentType.WORKSPACE_APP)],\n  [ResourceType.SCREEN]: [prefixed(DocumentType.SCREEN)],\n}\n\nconst validateDocMatchesPath = (importedDoc: ImportedDoc) => {\n  const id = importedDoc.doc._id\n  if (!id) {\n    throw new HTTPError(\"Project package contains a doc without an id.\", 400)\n  }\n\n  const expectedFileName = `${id}.json`\n  if (basename(importedDoc.path) !== expectedFileName) {\n    throw new HTTPError(`Project package doc path does not match '${id}'.`, 400)\n  }\n\n  const validPrefixes = RESOURCE_ID_PREFIXES[importedDoc.resourceType]\n  if (!validPrefixes.some(prefix => id.startsWith(prefix))) {\n    throw new HTTPError(\n      `Project package doc '${id}' does not match resource type '${importedDoc.resourceType}'.`,\n      400\n    )\n  }\n}\n\nconst remapObjectKeys = <T>(\n  value: Record<string, T>,\n  idMap: Map<string, string>\n) => {\n  return Object.fromEntries(\n    Object.entries(value).map(([key, nestedValue]) => [\n      idMap.get(key) || key,","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/backups/imports.ts#L328-L364","documentation":"validateDocMatchesPath requires the doc's filename to equal `<_id>.json`. If basename(importedDoc.path) differs from the id derived from the doc body, this HTTPError (400) is thrown — path and content must be consistent so imported docs land at predictable keys.","triggerScenarios":"A doc file renamed after export (e.g. `ta_abc.json` containing `_id: \"ta_abc123\"`), a doc copied to a differently-named file, or a doc whose `_id` was edited without renaming the file.","commonSituations":"Hand-editing package contents; deduplicating/merging exports by renaming files; scripts that regenerate ids; restoring docs into a package assembled by copying files between exports.","solutions":["Rename the file so it exactly matches the doc's `_id`: `mv old.json <_id>.json`.","Alternatively fix the `_id` inside the JSON to match the existing filename (only if you understand id-prefix semantics).","Re-export the project rather than manually editing package contents.","Add a pre-import check: for every .json, assert `basename === _id + '.json'`."],"exampleFix":"// before\n//   ta_abc.json contains { \"_id\": \"ta_abc123\", ... }\n// after\nmv ta_abc.json ta_abc123.json","handlingStrategy":"validation","validationCode":"import { basename } from \"path\"\n\nfunction docPathMatchesId(path: string, doc: { _id: string }): boolean {\n  return basename(path) === `${doc._id}.json`\n}\n// run for every entry in the docs directory before packaging","typeGuard":null,"tryCatchPattern":"try {\n  await api.importProjectPackage(file)\n} catch (err) {\n  if (err?.status === 400 && err.message.startsWith(\"Project package doc path does not match\")) {\n    // rename the file to `${_id}.json` (or fix the _id) and repackage\n  } else throw err\n}","preventionTips":["Never rename doc files after export","If editing an id, rename the file in the same change","Script a check: basename(path) === `${JSON.parse(content)._id}.json` for all docs","Prefer re-exporting over copying files between packages"],"tags":["http-400","import","path-validation","consistency-check"],"backgroundTag":"doc-path-id-mismatch","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}