Budibase/budibase · error
App not found with id "${workspaceApp._id}"
Error message
App not found with id "${workspaceApp._id}" What it means
After updating a workspace app via the API, edit() syncs the local store by finding the app's index by _id. If the updated app no longer exists in the local store list (index -1), it throws, indicating store state is out of sync with the server.
Source
Thrown at packages/builder/src/stores/builder/workspaceApps.ts:153
disabled: workspaceApp.disabled,
...(Object.hasOwn(workspaceApp, "projectIds")
? { projectIds: workspaceApp.projectIds }
: {}),
...(Object.hasOwn(workspaceApp, "theme")
? { theme: workspaceApp.theme }
: {}),
...(Object.hasOwn(workspaceApp, "customTheme")
? { customTheme: workspaceApp.customTheme }
: {}),
}
const updatedWorkspaceApp = await API.workspaceApp.update(safeWorkspaceApp)
this.store.update(state => {
const index = state.workspaceApps.findIndex(
app => app._id === workspaceApp._id
)
if (index === -1) {
throw new Error(`App not found with id "${workspaceApp._id}"`)
}
state.workspaceApps[index] = {
...updatedWorkspaceApp.workspaceApp,
}
return state
})
}
async delete(id: string, rev: string) {
await API.workspaceApp.delete(id, rev)
this.store.update(state => {
return {
...state,
workspaceApps: state.workspaceApps.filter(app => app._id !== id),
}
})View on GitHub (pinned to a81a902e9a)
Solutions
- Refresh the workspace apps list before toggling if it may be stale
- Check the app wasn't deleted in another tab/session; re-fetch via API.workspaceApp.fetch
- Verify the workspaceAppId passed to toggleDisabled is correct
- If hit inside edit() after a successful API update, reload the store state and retry
Example fix
// before await workspaceApps.toggleDisabled(appId, true) // after const exists = get(workspaceApps).workspaceApps.some(a => a._id === appId) if (!exists) await workspaceApps.fetch() await workspaceApps.toggleDisabled(appId, true)
Defensive patterns
Strategy: retry
Validate before calling
const existsLocally = get(workspaceApps).workspaceApps.some(a => a._id === appId) if (!existsLocally) await workspaceApps.fetch()
Try / catch
try {
await workspaceApps.toggleDisabled(appId, state)
} catch (e) {
if (e.message.startsWith("App not found with id")) {
await workspaceApps.fetch()
// re-check and inform user the app no longer exists
} else throw e
} Prevention
- Refresh the workspace apps list after external changes
- Avoid holding app ids across long-lived sessions without refresh
- Verify ids passed to toggleDisabled come from current store state
- Handle multi-tab deletion scenarios in the UI
When it happens
Trigger: toggleDisabled(workspaceAppId) calls edit() for an app id that was removed from the store (deleted elsewhere/concurrently) or never present locally, even though the API update succeeded.
Common situations: Two browser tabs — one deletes the app while the other toggles it; stale store after external deletion; passing a wrong/nonexistent _id to toggleDisabled; store not refreshed after another user's changes.
Related errors
- Failed to refresh saved group
- Workspace app not found ${workspaceAppId}
- Cannot render an empty flow chain
- Source table '${relationship.sourceTable}' not found in data
- Target table '${relationship.targetTable}' not found in data
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/3362b24f51261997.
Report an issue: GitHub.