{"record":{"id":"bf148fd2af18c946","repo":"Budibase/budibase","slug":"unable-to-find-table-id-in-request","errorCode":null,"errorMessage":"Unable to find table ID in request","messagePattern":"Unable to find table ID in request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/api/controllers/row/utils/utils.ts","lineNumber":82,"sourceCode":"  if (ctx.params?.sourceId) {\n    const { sourceId } = ctx.params\n    if (isViewId(sourceId)) {\n      return {\n        tableId: getTableIdFromViewId(sourceId),\n        viewId: sql.utils.encodeViewId(sourceId),\n      }\n    }\n    return { tableId: sql.utils.encodeTableId(ctx.params.sourceId) }\n  }\n  // now check for old way of specifying table ID\n  if (ctx.params?.tableId) {\n    return { tableId: sql.utils.encodeTableId(ctx.params.tableId) }\n  }\n  // check body for a table ID\n  if (ctx.request.body?.tableId) {\n    return { tableId: sql.utils.encodeTableId(ctx.request.body.tableId) }\n  }\n  throw new Error(\"Unable to find table ID in request\")\n}\n\nexport async function getSource(ctx: Ctx): Promise<Table | ViewV2> {\n  const { tableId, viewId } = getSourceId(ctx)\n  if (viewId) {\n    return sdk.views.get(viewId)\n  }\n  return sdk.tables.getTable(tableId)\n}\n\nexport async function getTableFromSource(source: Table | ViewV2) {\n  if (sdk.views.isView(source)) {\n    return await sdk.views.getTable(source.id)\n  }\n  return source\n}\n\nfunction fixBooleanFields(row: Row, table: Table) {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/row/utils/utils.ts#L64-L100","documentation":"Row API handlers need to know which table (and optionally view) they operate on. getSourceId() resolves it from ctx.params.sourceId, ctx.params.tableId, or ctx.request.body.tableId, in that priority order. If none is present the request is malformed for the row API and this error is thrown, which surfaces as a 500 for the caller.","triggerScenarios":"Any row endpoint (fetch/save/destroy/search) invoked without sourceId/tableId in the URL params AND without tableId in the request body; calling the API with a path that omits the table segment or sending a body missing the tableId field; custom/proxied requests built by hand that drop the table identifier.","commonSituations":"Hand-written curl/SDK calls to /api/rows-style endpoints missing the table ID; older integrations using deprecated URL shapes after the sourceId/tableId routing changed; template or automation code interpolating an empty/undefined tableId into the request path or body.","solutions":["Include the table ID in the URL path (e.g. /api/:tableId/rows or /api/:sourceId/rows).","If using a body-based route, add tableId to the JSON body: { \"tableId\": \"ta_...\", ... }.","Check that the variable interpolated into your request path/body is actually defined and non-empty.","If targeting a view, use the view ID as sourceId — it resolves both tableId and viewId."],"exampleFix":"// before\nawait api.post(\"/api/rows\", { name: \"x\" })\n// after\nawait api.post(`/api/${tableId}/rows`, { name: \"x\" })","handlingStrategy":"validation","validationCode":"// validate request shape before calling the row API\nfunction assertHasTableSource(opts: { path?: string; body?: Record<string, unknown> }) {\n  const inPath = /\\/(ta_|vd_)/.test(opts.path ?? \"\")\n  const inBody = typeof opts.body?.tableId === \"string\" && opts.body.tableId.length > 0\n  if (!inPath && !inBody) {\n    throw new Error(\"Request must include a tableId or sourceId\")\n  }\n}","typeGuard":"function hasTableId(body: unknown): body is { tableId: string } {\n  return typeof body === \"object\" && body !== null && typeof (body as { tableId?: unknown }).tableId === \"string\"\n}","tryCatchPattern":"try {\n  return await api.get(`/api/${tableId}/rows`)\n} catch (err) {\n  if (err.message === \"Unable to find table ID in request\") {\n    console.error(\"tableId missing from path/body — check interpolation\")\n  }\n  throw err\n}","preventionTips":["Always build row API URLs from a verified tableId/sourceId variable.","Log/validate request paths in dev to catch undefined table IDs early.","Prefer path-based table routing over body tableId for clarity.","When updating integrations, check the current routing scheme (sourceId vs tableId)."],"tags":["rest-api","validation","missing-parameter"],"backgroundTag":"missing-request-parameter","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}