Budibase/budibase · error · HTTPError
Resource not found: ${body.resourceId}
Error message
Resource not found: ${body.resourceId} What it means
Creating a workspace favourite first verifies the target resource exists via verifyResource. If the lookup returns no document (tryGet semantics) or the resource cannot be verified, a 404 HTTPError with the resource ID is raised, and any verification error is re-thrown as a 404 with a descriptive message.
Source
Thrown at packages/server/src/api/controllers/workspaceFavourites.ts:94
[WorkspaceResource.DATASOURCE]: sdk.datasources.get,
[WorkspaceResource.QUERY]: sdk.queries.find,
[WorkspaceResource.VIEW]: sdk.views.get,
[WorkspaceResource.AGENT]: sdk.ai.agents.getOrThrow,
}
const verifyResource: ResourceGetter = check[body.resourceType]
// Abort if it can't be verified
if (!verifyResource)
ctx.throw(
`Workspace favourite failure. Could not verify resource ${body.resourceId}, ${body.resourceType}`
)
// Attempt to find the resource to ensure that it exists
try {
const doc = await verifyResource(body.resourceId)
// tryGet doesnt throw so in the event that a resource doesn't throw, ensure it.
if (!doc) {
throw new HTTPError(`Resource not found: ${body.resourceId}`, 404)
}
} catch (e: any) {
ctx.throw(
404,
`Workspace favourite failure. Could not verify resource: ${body.resourceId}. ${e.message}`
)
}
const workspaceFavourite = await sdk.workspace.create(newFavourite)
ctx.status = 201
ctx.body = {
...workspaceFavourite,
} as AddWorkspaceFavouriteResponse
}
export async function destroy(
ctx: UserCtx<void, DeleteWorkspaceFavouriteResponse>
) {View on GitHub (pinned to a81a902e9a)
Solutions
- Verify the resource still exists (fetch its doc) and use a valid resourceId.
- Check the request is made in the workspace context of the app that owns the resource.
- Remove the stale favourite request from the client and refresh the resource list.
- If the resource was deleted intentionally, delete the favourite instead of creating it.
Example fix
// before
await api.post('/api/favourites', { resourceId: deletedRowId })
// after
const table = await api.get(`/api/tables/${tableId}`)
if (table) await api.post('/api/favourites', { resourceId: tableId }) Defensive patterns
Strategy: validation
Validate before calling
const doc = await verifyResource(resourceId)
if (!doc) return res.status(404).json({ error: `Resource ${resourceId} does not exist; cannot favourite` }) Type guard
const resourceExists = async (id: string): boolean => Boolean(await verifyResource(id))
Try / catch
try {
await api.post('/api/favourites', { resourceId })
} catch (e) {
if (e.status === 404 && /Could not verify resource/.test(e.message)) {
// refresh resource list, drop the stale favourite
} else throw e
} Prevention
- Refresh client caches of resource lists after deletes.
- Validate resourceId belongs to the current workspace before favouriting.
- Clean up favourites when their resources are deleted.
- Avoid hand-copying resource IDs between apps.
When it happens
Trigger: POSTing a favourite whose body.resourceId references a deleted or non-existent table/row/view/query/datasource, or an ID from a different workspace.
Common situations: Stale UI state favouriting an item deleted in another tab; copied resource IDs across apps; resources removed by import/restore operations.
Related errors
- Knowledge base not found
- Operation not found for this agent
- Custom REST template not found
- Automation not found
- Webhook not found
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/de020af9759cb483.
Report an issue: GitHub.