{"record":{"id":"71759e937f36fca3","repo":"mckaywrigley/chatbot-ui","slug":"error-message-71759e","errorCode":null,"errorMessage":"error.message","messagePattern":"error\\.message","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"db/files.ts","lineNumber":15,"sourceCode":"import { supabase } from \"@/lib/supabase/browser-client\"\nimport { TablesInsert, TablesUpdate } from \"@/supabase/types\"\nimport mammoth from \"mammoth\"\nimport { toast } from \"sonner\"\nimport { uploadFile } from \"./storage/files\"\n\nexport const getFileById = async (fileId: string) => {\n  const { data: file, error } = await supabase\n    .from(\"files\")\n    .select(\"*\")\n    .eq(\"id\", fileId)\n    .single()\n\n  if (!file) {\n    throw new Error(error.message)\n  }\n\n  return file\n}\n\nexport const getFileWorkspacesByWorkspaceId = async (workspaceId: string) => {\n  const { data: workspace, error } = await supabase\n    .from(\"workspaces\")\n    .select(\n      `\n      id,\n      name,\n      files (*)\n    `\n    )\n    .eq(\"id\", workspaceId)\n    .single()\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/mckaywrigley/chatbot-ui/blob/81328b61d2a4ab597a7a057be70e785cf756d9f8/db/files.ts#L1-L33","documentation":"Thrown when a single-row SELECT on the files table fails or returns no row. Note the bug in the source: it checks if (!file) but throws error.message — when the row genuinely doesn't exist, .single() sets error (PGRST116 'JSON object requested, multiple (or no) rows returned') and data is null, so the message is the PostgREST not-found message rather than a clear 'file not found'.","triggerScenarios":"Calling getFileById(fileId) with an id that doesn't exist, an id belonging to another user (RLS filters it out so zero rows return), or a genuine DB error (connection, permission).","commonSituations":"Deep-linking to a deleted file, using an anon key without RLS SELECT policies, stale fileId in client state after a re-seed of the database, or typo'd uuid.","solutions":["Verify the file id exists (select id from files where id = ...) with the service-role client or in the Supabase SQL editor","Add a SELECT RLS policy on files for authenticated users if rows are being filtered out","Fix the check to distinguish not-found from real errors (see exampleFix) and surface 'File not found' when error.code is PGRST116","Guard callers like fetchedFile to handle a null/missing file gracefully"],"exampleFix":"// before\nif (!file) {\n  throw new Error(error.message)\n}\n\n// after\nif (error || !file) {\n  if (error?.code === \"PGRST116\" || !file) throw new Error(\"File not found\")\n  throw new Error(`Failed to fetch file: ${error.message}`)\n}","handlingStrategy":"try-catch","validationCode":"const { data } = await supabase.from(\"files\").select(\"id\").eq(\"id\", fileId).maybeSingle()\nif (!data) throw new Error(\"File not found\")","typeGuard":"function isFileNotFound(e: unknown): boolean {\n  return e instanceof Error && /no rows|not found|PGRST116/i.test(e.message)\n}","tryCatchPattern":"try {\n  const file = await getFileById(fileId)\n} catch (e) {\n  if (isFileNotFound(e)) return notFound()\n  throw e\n}","preventionTips":["Use maybeSingle for optional lookups","Handle PGRST116 separately from real DB errors","Keep RLS SELECT policies aligned with ownership model"],"tags":["supabase","postgrest","not-found","single-row","rls"],"backgroundTag":"postgrest-single-row-not-found","analyzedSha":"81328b61d2a4ab597a7a057be70e785cf756d9f8","analyzedAt":"2026-08-27T19:24:42.689Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}