Budibase/budibase · error · HTTPError
Row not found
Error message
Row not found
What it means
Thrown by the external-row `find` SDK function when the underlying datasource returns no row for the requested rowId. `getRow` may resolve to undefined/null for external (SQL/plus) tables, and this guard converts that into an HTTP 404 so callers get a clear not-found signal.
Source
Thrown at packages/server/src/sdk/workspace/rows/external.ts:108
}
}
export async function find(tableOrViewId: string, rowId: string): Promise<Row> {
const { tableId, viewId } = tryExtractingTableAndViewId(tableOrViewId)
let source: Table | ViewV2
if (viewId) {
source = await sdk.views.get(viewId)
} else {
source = await sdk.tables.getTable(tableId)
}
const row = await getRow(source, rowId, {
relationships: true,
})
if (!row) {
throw new HTTPError("Row not found", 404)
}
// Preserving links, as the outputProcessing does not support external rows
// yet and we don't need it in this use case
return await outputProcessing(source, row, {
squash: true,
preserveLinks: true,
})
}
View on GitHub (pinned to a81a902e9a)
Solutions
- Verify the rowId exists in the datasource before calling find
- Re-fetch the table/dataSource schema in case the table was rebuilt and IDs changed
- Check you are querying the correct tableId for the row ID
- Handle the 404 gracefully in the caller instead of treating it as a server fault
Example fix
// before
const row = await sdk.rows.find(tableId, staleRowId)
// after
let row
try {
row = await sdk.rows.find(tableId, rowId)
} catch (e) {
if (e.status === 404) return null
throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
const exists = rowId && (await sdk.rows.search({ tableId, query: { _id: rowId }, limit: 1 })).rows.length > 0 Type guard
function isRowFound(row: Row | null | undefined): row is Row { return !!row && !!row._id } Try / catch
try { const row = await sdk.rows.find(tableId, rowId) } catch (e) { if ((e as HTTPError).status === 404) { /* not found path */ } else throw e } Prevention
- Validate rowId format before lookup
- Re-sync external datasources before lookups after schema changes
- Never assume IDs from one table are valid in another
- Handle 404 as a normal control-flow case in UIs
When it happens
Trigger: Calling sdk.rows.find (or the row API) with a rowId that does not exist in an external datasource table, a row deleted concurrently, or a malformed/composite row ID from a different table.
Common situations: Stale row IDs cached in the client after a table rebuild; searching an external (Postgres/MySQL) table where the row was removed upstream; passing an internal CouchDB row ID to an external table lookup.
Related errors
- Error getting account by tenantId ${tenantId}
- 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/3ab01bc8a910e999.
Report an issue: GitHub.