{"record":{"id":"e6b2522fa8e542c8","repo":"Budibase/budibase","slug":"workspace-app-should-be-defined","errorCode":null,"errorMessage":"Workspace app should be defined","messagePattern":"Workspace app should be defined","errorType":"http","errorClass":"HTTPError","httpStatus":500,"severity":"error","filePath":"packages/server/src/sdk/workspace/navigation/index.ts","lineNumber":18,"sourceCode":"import { HTTPError } from \"@budibase/backend-core\"\nimport sdk from \"../..\"\nimport { AppNavigation } from \"@budibase/types\"\n\nexport async function addLink({\n  label,\n  url,\n  roleId,\n  workspaceAppId,\n}: {\n  label: string\n  url: string\n  roleId: string\n  workspaceAppId: string\n}) {\n  const workspaceApp = await sdk.workspaceApps.get(workspaceAppId)\n  if (!workspaceApp) {\n    throw new HTTPError(\"Workspace app should be defined\", 500)\n  }\n  workspaceApp.navigation.links ??= []\n  workspaceApp.navigation.links.push({\n    text: label,\n    url,\n    roleId,\n    type: \"link\",\n  })\n\n  await sdk.workspaceApps.update(workspaceApp)\n}\n\nexport async function deleteLink(route: string, workspaceAppId: string) {\n  const workspaceApp = (await sdk.workspaceApps.get(workspaceAppId!))!\n  workspaceApp.navigation.links ??= []\n\n  // Filter out top level links pointing to these URLs\n  const updatedLinks = workspaceApp.navigation.links.filter(","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/navigation/index.ts#L1-L36","documentation":"addLink fetches the target workspace app and throws HTTP 500 'Workspace app should be defined' when sdk.workspaceApps.get returns nothing. This is an internal invariant failure: the caller supplied a workspaceAppId that does not resolve to an existing workspace app, so a navigation link cannot be appended.","triggerScenarios":"Calling addLink with a workspaceAppId that is undefined, deleted, or belongs to a different workspace — e.g. a stale ID cached in automation/script code, or a route param that never matched a real app document.","commonSituations":"Apps deleted while a client still holds their ID; cross-workspace ID reuse; copy-pasted IDs between dev/prod environments.","solutions":["Verify the workspaceAppId exists via sdk.workspaceApps.get or the apps API before calling addLink","Re-fetch the current workspace app list and use a fresh ID if the app was recreated","Ensure the call runs in the workspace context that owns the app"],"exampleFix":"// before\nawait addLink({ workspaceAppId: staleId, ... }) // app deleted -> 500\n// after\nconst app = await sdk.workspaceApps.get(workspaceAppId)\nif (app) await addLink({ workspaceAppId: app._id!, ... })","handlingStrategy":"validation","validationCode":"const app = await sdk.workspaceApps.get(workspaceAppId)\nif (!app) throw new Error(`Workspace app ${workspaceAppId} not found; cannot add link`)","typeGuard":null,"tryCatchPattern":"try {\n  await navigation.addLink({ workspaceAppId, label, url, roleId })\n} catch (err) {\n  if (err instanceof HTTPError && err.status === 500 && /should be defined/.test(err.message)) {\n    // stale workspaceAppId — refresh app list and retry once with a valid ID\n    return\n  }\n  throw err\n}","preventionTips":["Fetch workspace apps fresh before mutating their navigation","Don't cache workspaceAppIds across app deletion/recreation","Ensure calls run in the workspace context owning the app"],"tags":["navigation","workspace-app","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}