{"record":{"id":"d5f4449f85949a16","repo":"mckaywrigley/chatbot-ui","slug":"error-message-d5f444","errorCode":null,"errorMessage":"error.message","messagePattern":"error\\.message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"db/models.ts","lineNumber":12,"sourceCode":"import { supabase } from \"@/lib/supabase/browser-client\"\nimport { TablesInsert, TablesUpdate } from \"@/supabase/types\"\n\nexport const getModelById = async (modelId: string) => {\n  const { data: model, error } = await supabase\n    .from(\"models\")\n    .select(\"*\")\n    .eq(\"id\", modelId)\n    .single()\n\n  if (!model) {\n    throw new Error(error.message)\n  }\n\n  return model\n}\n\nexport const getModelWorkspacesByWorkspaceId = async (workspaceId: string) => {\n  const { data: workspace, error } = await supabase\n    .from(\"workspaces\")\n    .select(\n      `\n      id,\n      name,\n      models (*)\n    `\n    )\n    .eq(\"id\", workspaceId)\n    .single()\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/mckaywrigley/chatbot-ui/blob/81328b61d2a4ab597a7a057be70e785cf756d9f8/db/models.ts#L1-L30","documentation":"The code intends to report a Supabase lookup failure for a model by id, but the guard is buggy: it checks `if (!model)` and throws `error.message`. When PostgREST succeeds but zero rows match, model is null AND error carries PGRST116 ('JSON object requested, multiple (or no) rows returned') — so this usually surfaces as a not-found error. Conversely a genuine query error with a truthy error also lands here, conflating two distinct cases.","triggerScenarios":"Calling getModelById with an id that doesn't exist in 'models' (`.single()` returns null data + PGRST116 error); passing a malformed UUID; or any query-level failure (RLS SELECT policy blocking reads, connection issue) — all funnel into the same throw.","commonSituations":"Looking up a model deleted by another workspace member; RLS SELECT policies hiding rows from the current user so every lookup by foreign id appears 'not found'; id strings taken from query params without UUID validation.","solutions":["Fix the guard: check `if (error)` first, then handle null data as a not-found case separately","Use `.maybeSingle()` instead of `.single()` so zero-row results return null data with no error, then branch on data","Validate modelId is a UUID before querying to get a clearer error"],"exampleFix":"// before\nif (!model) {\n  throw new Error(error.message)\n}\nreturn model\n\n// after\nif (error) {\n  throw new Error(`getModelById failed [${error.code}]: ${error.message}`)\n}\nif (!model) {\n  throw new Error(`Model ${modelId} not found`)\n}\nreturn model","handlingStrategy":"type-guard","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\nif (!UUID_RE.test(modelId)) throw new Error(`invalid model id: ${modelId}`)","typeGuard":"const isModel = (m: unknown): m is Tables<\"models\"> =>\n  typeof m === \"object\" && m !== null && \"id\" in m && \"user_id\" in m","tryCatchPattern":"try {\n  return await getModelById(modelId)\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e)\n  if (msg.includes(\"PGRST116\") || /no rows/i.test(msg)) throw new NotFoundError(`model ${modelId}`)\n  throw e\n}","preventionTips":["Use maybeSingle() and branch on null instead of .single() for lookups","Wrap lookups in a findModel returning null rather than throwing when absence is expected","Validate UUID format before hitting the database"],"tags":["supabase","not-found","logic-bug","postgres","type-guard"],"backgroundTag":"supabase-single-row-not-found","analyzedSha":"81328b61d2a4ab597a7a057be70e785cf756d9f8","analyzedAt":"2026-08-27T19:24:42.689Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}