Budibase/budibase · error · HTTPError
Workspace app not found
Error message
Workspace app not found
What it means
update replaces a workspace app's navigation but first checks the app exists; when sdk.workspaceApps.get returns nothing it throws HTTP 400 'Workspace app not found'. Unlike addLink's 500, this is treated as a client error: the caller supplied an unknown or deleted workspaceAppId.
Source
Thrown at packages/server/src/sdk/workspace/navigation/index.ts:59
updatedLinks.forEach(link => {
if (link.type === "sublinks" && link.subLinks?.length) {
link.subLinks = link.subLinks.filter(subLink => subLink.url !== route)
}
})
await sdk.workspaceApps.update({
...workspaceApp,
navigation: { ...workspaceApp.navigation, links: updatedLinks },
})
}
export async function update(
workspaceAppId: string,
navigation: AppNavigation
) {
const workspaceApp = await sdk.workspaceApps.get(workspaceAppId)
if (!workspaceApp) {
throw new HTTPError("Workspace app not found", 400)
}
await sdk.workspaceApps.update({ ...workspaceApp, navigation })
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Confirm the workspaceAppId against the workspace app list API before updating
- Re-create the app or pick a valid ID if it was deleted
- Verify the tenancy/workspace context of the request so the lookup queries the correct database
Example fix
// before
await update(deletedAppId, navigation) // 400 Workspace app not found
// after
const app = await sdk.workspaceApps.get(deletedAppId)
if (!app) throw new Error("Pick a valid workspace app before updating navigation")
await update(app._id!, navigation) Defensive patterns
Strategy: try-catch
Validate before calling
const app = await sdk.workspaceApps.get(workspaceAppId)
if (!app) {
throw new HTTPError(`Workspace app ${workspaceAppId} not found`, 400)
} Try / catch
try {
await navigation.update(workspaceAppId, navigation)
} catch (err) {
if (err instanceof HTTPError && err.status === 400 && err.message === "Workspace app not found") {
// pick a valid app or surface a user-facing message
return
}
throw err
} Prevention
- Verify the app exists via the workspace apps API before updating navigation
- Watch for indirect failures via addLink/deleteLink which call update internally
- Check tenant/workspace context when IDs look valid but lookups return nothing
When it happens
Trigger: Calling update(workspaceAppId, navigation) with an ID that does not exist in the current workspace DB, was deleted, or was created in a different workspace/tenant; also surfaces indirectly through addLink/deleteLink which route through update.
Common situations: Builder UI holding a stale app ID after the app was removed; automation steps referencing an app from another environment; tenant context misconfiguration so the lookup hits the wrong DB.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Workspace app should be defined
- Row action '${rowActionId}' not found in '${tableId}'
- View '${viewId}' not found in '${tableId}'
- Workspace app not found ${workspaceAppId}
- Agent not found
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/b93e015378182171.
Report an issue: GitHub.