Budibase/budibase · error · HTTPError
Row not found
Error message
Row not found
What it means
Thrown by run in packages/server/src/sdk/workspace/rowActions/crud.ts when a sourceId view is supplied and a row search on that view (query equal _id = rowId, limit 1) returns no rows. This guards execution so a row action only runs for rows actually visible through the given (non-calculation) view.
Source
Thrown at packages/server/src/sdk/workspace/rowActions/crud.ts:260
rowActionId: any,
rowId: string,
user: User,
sourceId?: string
) {
const table = await sdk.tables.getTable(tableId)
if (!table) {
throw new HTTPError("Table not found", 404)
}
if (sourceId && isViewId(sourceId)) {
const result = await sdk.rows.search({
tableId,
viewId: sourceId,
query: { equal: { _id: rowId } },
limit: 1,
})
if (!result.rows.length) {
throw new HTTPError("Row not found", 404)
}
}
const { automationId } = await get(tableId, rowActionId)
const automation = await sdk.automations.get(automationId)
const row = await sdk.rows.find(tableId, rowId)
await triggers.externalTrigger(
automation,
{
fields: {
id: row._id,
revision: row._rev,
row,
table,
},
user,
appId: context.getWorkspaceId(),View on GitHub (pinned to a81a902e9a)
Solutions
- Verify the rowId exists and satisfies the view's filters, or run the action with the table's base source (omit sourceId) if the view filter is excluding it legitimately.
- Confirm the rowId belongs to the same tableId as the row action.
- Re-fetch the row before running the action to handle deletion races.
Example fix
// before
await rowActions.run(tableId, rowActionId, rowId, user, viewId) // row filtered out of view
// after
const visible = await sdk.rows.search({ tableId, viewId, query: { equal: { _id: rowId } }, limit: 1 })
if (visible.rows.length) await rowActions.run(tableId, rowActionId, rowId, user, viewId) Defensive patterns
Strategy: validation
Validate before calling
const result = await sdk.rows.search({
tableId,
viewId: sourceViewId,
query: { equal: { _id: rowId } },
limit: 1,
})
if (!result.rows.length) throw new Error(`Row ${rowId} is not visible through view ${sourceViewId}`) Try / catch
try {
await rowActions.run(tableId, rowActionId, rowId, user, viewId)
} catch (e) {
if (e instanceof HTTPError && e.status === 404 && e.message === "Row not found") {
// retry with table-level source (omit sourceId) or skip — row filtered/deleted
} else throw e
} Prevention
- Remember view filters: a row present in the table may be invisible to the view.
- Re-check row existence immediately before running actions to avoid delete races.
- Ensure rowIds are fetched from the same table/view the action targets.
When it happens
Trigger: Calling run(tableId, rowActionId, rowId, user, viewSourceId) where the row does not exist, exists but is filtered out by the view's query/filters, or belongs to a different table.
Common situations: Running actions against rows hidden by view filters — the row exists in the table but not in the view; passing a rowId from another table; the row was deleted between listing and running the action.
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
- View '${viewId}' not found in '${tableId}'
- Table not found
- View ${view.id} not found in table ${tableId}
- Operation not found for this agent
- Custom REST template not found
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/3a0924f397f16272.
Report an issue: GitHub.