Budibase/budibase · error · HTTPError
View '${viewId}' not found in '${tableId}'
Error message
View '${viewId}' not found in '${tableId}' What it means
Thrown by guardView in packages/server/src/sdk/workspace/rowActions/crud.ts when setting or unsetting a view-level permission for a view that either does not exist or does not belong to the given table. guardView only resolves the view when isViewId(viewId) is true, then verifies view.tableId matches tableId.
Source
Thrown at packages/server/src/sdk/workspace/rowActions/crud.ts:182
const updated = await transformer(actionsDoc)
const db = context.getWorkspaceDB()
await db.put(updated)
return {
id: rowActionId,
...updated.actions[rowActionId],
}
}
async function guardView(tableId: string, viewId: string) {
let view
if (isViewId(viewId)) {
view = await sdk.views.get(viewId)
}
if (!view || view.tableId !== tableId) {
throw new HTTPError(`View '${viewId}' not found in '${tableId}'`, 400)
}
}
export async function setTablePermission(tableId: string, rowActionId: string) {
return await updateDoc(tableId, rowActionId, async actionsDoc => {
actionsDoc.actions[rowActionId].permissions.table.runAllowed = true
return actionsDoc
})
}
export async function unsetTablePermission(
tableId: string,
rowActionId: string
) {
return await updateDoc(tableId, rowActionId, async actionsDoc => {
actionsDoc.actions[rowActionId].permissions.table.runAllowed = false
return actionsDoc
})View on GitHub (pinned to a81a902e9a)
Solutions
- Pass a valid view id (formatted as a view id, e.g. 'data_view_...') rather than a table or row id.
- Confirm the view belongs to the same tableId you pass; fetch the view via sdk.views.get and compare tableId.
- Re-fetch the table's views list if the view may have been deleted recently.
Example fix
// before await rowActions.setViewPermission(tableId, rowActionId, tableId /* wrong: table id as viewId */) // after const viewId = table.views["my_view"]?.id if (viewId && isViewId(viewId)) await rowActions.setViewPermission(tableId, rowActionId, viewId)
Defensive patterns
Strategy: validation
Validate before calling
if (!isViewId(viewId)) throw new Error("setViewPermission requires a view id")
const view = await sdk.views.get(viewId)
if (!view || view.tableId !== tableId) throw new Error(`View ${viewId} is not part of table ${tableId}`) Type guard
const isValidViewForTable = (view: View | undefined, tableId: string): view is View => !!view && view.tableId === tableId
Try / catch
try {
await rowActions.setViewPermission(tableId, rowActionId, viewId)
} catch (e) {
if (e instanceof HTTPError && e.status === 400) {
// wrong or missing view id: re-resolve from table.views
} else throw e
} Prevention
- Resolve view ids from table.views rather than passing table or row ids.
- Use isViewId to validate id format before any view-scoped call.
- Verify view.tableId matches your target table before permission changes.
When it happens
Trigger: Calling setViewPermission/unsetViewPermission with a viewId that fails isViewId (so view stays undefined), a deleted view id, or a valid view id whose view.tableId differs from the supplied tableId.
Common situations: Passing a table id where a view id is expected; view deleted from the table while the client still holds its id; cross-table mix-up after copying permission code between tables.
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
- Row action '${rowActionId}' not found in '${tableId}'
- Row not found
- Workspace app not found
- Table not found
- Cannot insert rows through a calculation view
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/686038d2ea092fcf.
Report an issue: GitHub.