{"record":{"id":"3ab01bc8a910e999","repo":"Budibase/budibase","slug":"row-not-found-3ab01b","errorCode":null,"errorMessage":"Row not found","messagePattern":"Row not found","errorType":"http","errorClass":"HTTPError","httpStatus":404,"severity":"error","filePath":"packages/server/src/sdk/workspace/rows/external.ts","lineNumber":108,"sourceCode":"  }\n}\n\nexport async function find(tableOrViewId: string, rowId: string): Promise<Row> {\n  const { tableId, viewId } = tryExtractingTableAndViewId(tableOrViewId)\n\n  let source: Table | ViewV2\n  if (viewId) {\n    source = await sdk.views.get(viewId)\n  } else {\n    source = await sdk.tables.getTable(tableId)\n  }\n\n  const row = await getRow(source, rowId, {\n    relationships: true,\n  })\n\n  if (!row) {\n    throw new HTTPError(\"Row not found\", 404)\n  }\n\n  // Preserving links, as the outputProcessing does not support external rows\n  // yet and we don't need it in this use case\n  return await outputProcessing(source, row, {\n    squash: true,\n    preserveLinks: true,\n  })\n}\n","sourceCodeStart":90,"sourceCodeEnd":118,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/rows/external.ts#L90-L118","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst row = await sdk.rows.find(tableId, staleRowId)\n// after\nlet row\ntry {\n  row = await sdk.rows.find(tableId, rowId)\n} catch (e) {\n  if (e.status === 404) return null\n  throw e\n}","handlingStrategy":"try-catch","validationCode":"const exists = rowId && (await sdk.rows.search({ tableId, query: { _id: rowId }, limit: 1 })).rows.length > 0","typeGuard":"function isRowFound(row: Row | null | undefined): row is Row { return !!row && !!row._id }","tryCatchPattern":"try { const row = await sdk.rows.find(tableId, rowId) } catch (e) { if ((e as HTTPError).status === 404) { /* not found path */ } else throw e }","preventionTips":["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"],"tags":["http-404","external-tables","row-lookup"],"backgroundTag":"resource-not-found-404","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}