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

  1. Verify the rowId exists in the datasource before calling find
  2. Re-fetch the table/dataSource schema in case the table was rebuilt and IDs changed
  3. Check you are querying the correct tableId for the row ID
  4. 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

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


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