{"record":{"id":"98abfc74ecf6c674","repo":"Budibase/budibase","slug":"project-projectid-not-found","errorCode":null,"errorMessage":"Project '${projectId}' not found","messagePattern":"Project '(.+?)' not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/sdk/workspace/projects/backups/exports.ts","lineNumber":324,"sourceCode":"      await encryptDirectory(fullPath, password)\n    }\n  }\n}\n\nexport async function exportProject(\n  projectId: string,\n  opts?: {\n    encryptPassword?: string\n  }\n) {\n  const workspaceId = context.getWorkspaceId()\n  if (!workspaceId) {\n    throw new Error(\"Could not determine workspace for Project export\")\n  }\n\n  const project = await sdk.projects.get(projectId)\n  if (!project) {\n    throw new Error(`Project '${projectId}' not found`)\n  }\n\n  const graph = await sdk.resources.getResourcesInfo()\n  const projectDependencies = sortResources(\n    Array.from(\n      new Map(\n        (graph[projectId]?.dependencies || []).map(resource => [\n          resource.id,\n          resource,\n        ])\n      ).values()\n    )\n  )\n  const [agents, workspaceApps] = await Promise.all([\n    sdk.ai.agents.fetch(),\n    sdk.workspaceApps.fetch(),\n  ])\n  const directMembers = await getDirectMembers(projectId)","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/backups/exports.ts#L306-L342","documentation":"exportProject loads the workspace/project document via sdk.projects.get(projectId) before building the export tar. If the returned project is falsy, it throws this plain Error because an export cannot proceed without the project metadata. Note the separate earlier check for workspaceId, so this specifically means the project document itself was not found.","triggerScenarios":"Calling exportProject with a projectId/appId that does not exist in the current tenant, was deleted, or where the context is set to a different workspace so the lookup misses; also when get() swallows a DB error and returns undefined.","commonSituations":"Automations/scripts exporting an app id from a different environment; app deleted while an export job was queued; typos or missing prefix in the project id; backups running against an app mid-deletion.","solutions":["Verify the projectId exists (list workspaces/apps) and is passed with correct casing/prefix","Ensure the export runs inside the correct workspace context","Check the app was not recently deleted (recycle bin) and restore it if needed","Re-run the export after confirming app health"],"exampleFix":"// before\nawait exportProject({ projectId: copiedFromOtherEnv })\n// after\nconst project = await sdk.projects.get(projectId)\nif (!project) {\n  throw new Error(`Cannot export: project ${projectId} missing in this tenant`)\n}\nawait exportProject({ projectId })","handlingStrategy":"validation","validationCode":"const project = await sdk.projects.get(projectId)\nif (!project) throw new Error(`Project ${projectId} not found in this tenant; aborting export`)","typeGuard":"function projectExists(\n  p: Project | undefined | null\n): p is Project {\n  return !!p && typeof p._id === \"string\"\n}","tryCatchPattern":"try {\n  await exportProject({ projectId })\n} catch (e) {\n  if (String(e.message).includes(\"not found\")) {\n    // verify app id / workspace context before retrying\n  } else throw e\n}","preventionTips":["Confirm the app id against the tenant's app list before scripted exports","Run exports inside the correct workspace context","Check the app wasn't deleted between job scheduling and execution"],"tags":["export","not-found","backups"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}