{"record":{"id":"e123c478a15b2917","repo":"Budibase/budibase","slug":"project-app-with-id-workspaceapp-id-not-foun","errorCode":null,"errorMessage":"Project app with id '${workspaceApp._id}' not found.","messagePattern":"Project app with id '(.+?)' not found\\.","errorType":"http","errorClass":"HTTPError","httpStatus":404,"severity":"error","filePath":"packages/server/src/sdk/workspace/workspaceApps/crud.ts","lineNumber":138,"sourceCode":"  return response.doc\n}\n\nexport async function duplicate(\n  appToDuplicate: WorkspaceApp\n): Promise<WorkspaceApp> {\n  const duplicated = await createDuplicatedApp(appToDuplicate)\n  await duplicateScreens(appToDuplicate._id as string, duplicated._id as string)\n  return duplicated\n}\n\nexport async function update(\n  workspaceApp: WorkspaceAppUpdate\n): Promise<WorkspaceApp> {\n  const db = context.getWorkspaceDB()\n\n  const persisted = await get(workspaceApp._id!)\n  if (!persisted) {\n    throw new HTTPError(\n      `Project app with id '${workspaceApp._id}' not found.`,\n      404\n    )\n  }\n  if (workspaceApp.name !== persisted.name) {\n    await guardName(workspaceApp.name, workspaceApp._id)\n  }\n  const docToUpdate: RequiredKeys<WorkspaceApp> = {\n    _id: workspaceApp._id,\n    _rev: workspaceApp._rev,\n    name: workspaceApp.name,\n    url: workspaceApp.url,\n    navigation: workspaceApp.navigation,\n    theme: hasOwn(workspaceApp, \"theme\") ? workspaceApp.theme : persisted.theme,\n    customTheme: hasOwn(workspaceApp, \"customTheme\")\n      ? workspaceApp.customTheme\n      : persisted.customTheme,\n    disabled: workspaceApp.disabled,","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/workspaceApps/crud.ts#L120-L156","documentation":"update() fetches the persisted workspace app by _id before writing; if get() returns undefined the id does not exist in the workspace DB and a 404 HTTPError is thrown. This protects against updating non-existent or foreign-doc ids.","triggerScenarios":"Calling sdk.workspaceApps.update with a WorkspaceAppUpdate whose _id does not exist in the current workspace DB — e.g. a stale/hardcoded id, an id from another app/workspace, or an app already deleted.","commonSituations":"Frontend holding an outdated list after the app was deleted elsewhere; ids copied across environments (dev vs prod workspace dbs differ); wrong workspace context set so the doc isn't in the active DB.","solutions":["Verify the _id exists via sdk.workspaceApps.fetch()/get() before updating","Ensure the correct workspace/app context is active so context.getWorkspaceDB() points at the right DB","Fetch fresh docs to also get a current _rev before updating"],"exampleFix":"// before\nawait sdk.workspaceApps.update({ _id: someId, name: 'New', url: '/new' })\n// after\nconst persisted = await sdk.workspaceApps.get(someId)\nif (!persisted) throw new Error(`Workspace app ${someId} not found`)\nawait sdk.workspaceApps.update({ ...persisted, name: 'New' })","handlingStrategy":"validation","validationCode":"const persisted = await sdk.workspaceApps.get(id)\nif (!persisted) throw new Error(`Workspace app ${id} not found in this workspace`)","typeGuard":"function workspaceAppExists(app) {\n  return app !== undefined && typeof app === 'object' && !!app._id && !!app._rev\n}","tryCatchPattern":"try {\n  await sdk.workspaceApps.update(update)\n} catch (e) {\n  if (e?.status === 404) {\n    // refresh the app list; the id is stale or from another workspace\n  } else throw e\n}","preventionTips":["Always fetch the doc first and spread it to keep _id/_rev current","Confirm the correct workspace context is active before updates","Never hardcode workspace app ids across environments"],"tags":["not-found","http-404","workspace-apps"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}