{"record":{"id":"4e2fe66530fd1043","repo":"Budibase/budibase","slug":"view-view-id-not-found-in-table-tableid","errorCode":null,"errorMessage":"View ${view.id} not found in table ${tableId}","messagePattern":"View (.+?) not found in table (.+?)","errorType":"http","errorClass":"HTTPError","httpStatus":404,"severity":"error","filePath":"packages/server/src/sdk/workspace/views/external.ts","lineNumber":88,"sourceCode":"  return view\n}\n\nexport async function update(\n  tableId: string,\n  view: Readonly<ViewV2>\n): Promise<{ view: Readonly<ViewV2>; existingView: ViewV2 }> {\n  const db = context.getWorkspaceDB()\n\n  const { datasourceId, tableName } = breakExternalTableId(tableId)\n  const ds = await sdk.datasources.get(datasourceId)\n  ds.entities![tableName].views ??= {}\n  const views = ds.entities![tableName].views!\n\n  const existingView = Object.values(views).find(\n    v => isV2(v) && v.id === view.id\n  )\n  if (!existingView || !existingView.name) {\n    throw new HTTPError(`View ${view.id} not found in table ${tableId}`, 404)\n  }\n  if (isV2(existingView) && existingView.type !== view.type) {\n    throw new HTTPError(`Cannot update view type after creation`, 400)\n  }\n\n  view = ensureQuerySet(view)\n  view = ensureQueryUISet(view)\n\n  delete views[existingView.name]\n  views[view.name] = view\n  await db.put(ds)\n  return { view, existingView } as { view: ViewV2; existingView: ViewV2 }\n}\n\nexport async function remove(viewId: string): Promise<ViewV2> {\n  const db = context.getWorkspaceDB()\n\n  const view = await get(viewId)","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/views/external.ts#L70-L106","documentation":"Thrown by the view V2 update path for external (SQL) datasources when the view id being updated cannot be matched against any V2 view stored on the target table. The update flow loads the datasource document, looks up an existing view by id in table.views, and 404s if it is absent or has no name, because update is only meaningful for an existing view.","triggerScenarios":"Calling sdk.views.external.update (or the PUT view API) with a tableId and a ViewV2 whose id does not exist in ds.entities[tableName].views, the view is a V1 legacy view (filtered out by isV2), or the view was deleted by another request before the update.","commonSituations":"Stale client state updating a view deleted in another tab/session; using an internal-table view id against an external table; passing a fabricated or wrong view id; datasource document regenerated so view ids no longer match.","solutions":["Fetch the view first (sdk.views.get / getEnriched) and confirm the id exists before updating","Verify the view id belongs to the same external tableId passed to update","Use create instead of update when the view does not yet exist","Refresh client state and retry with a freshly loaded view"],"exampleFix":"// before\nawait sdk.views.update(tableId, { id: \"view_stale\", ...view })\n// after\nconst existing = await sdk.views.get(view.id).catch(() => null)\nif (!existing) view = await sdk.views.create(tableId, view)\nelse await sdk.views.update(tableId, view)","handlingStrategy":"validation","validationCode":"const views = Object.values(ds.entities[tableName]?.views ?? {}).filter(isV2)\nif (!views.some(v => v.id === view.id)) throw new Error(`View ${view.id} missing; create it instead`)","typeGuard":"function isV2View(v: unknown): v is ViewV2 {\n  return typeof v === \"object\" && v !== null && \"id\" in v && (v as ViewV2).version === 2\n}","tryCatchPattern":"try { await sdk.views.update(tableId, view) }\ncatch (e) {\n  if (e instanceof HTTPError && e.status === 404) await sdk.views.create(tableId, view)\n  else throw e\n}","preventionTips":["Always load the view via sdk.views.get before updating","Never cache view ids across datasource refreshes","Distinguish create vs update flows by existence check","Match the view id to the exact tableId passed to update"],"tags":["http-404","views","external-datasource"],"backgroundTag":"view-not-found","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}