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

  1. Refresh the workspace apps list before toggling if it may be stale
  2. Check the app wasn't deleted in another tab/session; re-fetch via API.workspaceApp.fetch
  3. Verify the workspaceAppId passed to toggleDisabled is correct
  4. 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

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


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/3362b24f51261997. Report an issue: GitHub.