{"record":{"id":"4c5d7d4d26032f67","repo":"Budibase/budibase","slug":"project-app-with-id-workspaceappid-not-found","errorCode":null,"errorMessage":"Project app with id '${workspaceAppId}' 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":181,"sourceCode":"    createdAt: persisted.createdAt,\n    updatedAt: persisted.updatedAt,\n    isDefault: persisted.isDefault,\n    _deleted: undefined,\n  }\n  const response = await db.put(docToUpdate, { returnDoc: true })\n  events.workspace.appUpdated(response.doc, context.getWorkspaceId()!)\n  return response.doc\n}\n\nexport async function remove(\n  workspaceAppId: string,\n  _rev: string\n): Promise<void> {\n  const db = context.getWorkspaceDB()\n  try {\n    const existing = await db.tryGet<WorkspaceApp>(workspaceAppId)\n    if (!existing)\n      throw new HTTPError(\n        `Project app with id '${workspaceAppId}' not found.`,\n        404\n      )\n\n    await db.remove(workspaceAppId, _rev)\n\n    // Clear out any favourites related to this\n    events.workspace.appDeleted(existing, context.getWorkspaceId()!)\n  } catch (e: any) {\n    if (e.status === 404) {\n      throw new HTTPError(\n        `Project app with id '${workspaceAppId}' not found.`,\n        404\n      )\n    }\n    throw e\n  }\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/workspaceApps/crud.ts#L163-L199","documentation":"remove() tries to fetch the workspace app with db.tryGet; if it does not exist it throws a 404 HTTPError before attempting deletion. The surrounding catch also re-wraps any 404-status error with the same message.","triggerScenarios":"Calling sdk.workspaceApps.remove(workspaceAppId, _rev) with an id that is not present in the workspace DB — already deleted, never existed, or wrong workspace context.","commonSituations":"Double-delete (retry after a successful removal); deleting from a UI list that is stale; ids passed from another app's DB; wrong context so the lookup misses.","solutions":["Check existence with sdk.workspaceApps.get(id) before calling remove","Treat 404 as idempotent success if the goal is 'ensure deleted'","Confirm the workspace context/DB contains the doc (fetch first)"],"exampleFix":"// before\nawait sdk.workspaceApps.remove(id, rev)\n// after\nconst existing = await sdk.workspaceApps.get(id)\nif (existing) await sdk.workspaceApps.remove(id, existing._rev!)","handlingStrategy":"try-catch","validationCode":"const existing = await sdk.workspaceApps.get(workspaceAppId)\nif (!existing) return // nothing to delete","typeGuard":"function isWorkspaceApp(doc) {\n  return !!doc && typeof doc === 'object' && '_id' in doc && '_rev' in doc\n}","tryCatchPattern":"try {\n  await sdk.workspaceApps.remove(id, rev)\n} catch (e) {\n  if (e?.status === 404) return // treat as already deleted\n  throw e\n}","preventionTips":["Fetch the doc to get a fresh _rev immediately before removal","Treat 404 as idempotent success in delete workflows","Disable the delete action after the first click to avoid double deletes"],"tags":["not-found","http-404","workspace-apps","delete"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}