mckaywrigley/chatbot-ui · error · Error

error.message

Error message

error.message

What it means

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.

Source

Thrown at db/models.ts:12

import { supabase } from "@/lib/supabase/browser-client"
import { TablesInsert, TablesUpdate } from "@/supabase/types"

export const getModelById = async (modelId: string) => {
  const { data: model, error } = await supabase
    .from("models")
    .select("*")
    .eq("id", modelId)
    .single()

  if (!model) {
    throw new Error(error.message)
  }

  return model
}

export const getModelWorkspacesByWorkspaceId = async (workspaceId: string) => {
  const { data: workspace, error } = await supabase
    .from("workspaces")
    .select(
      `
      id,
      name,
      models (*)
    `
    )
    .eq("id", workspaceId)
    .single()

View on GitHub (pinned to 81328b61d2)

Solutions

  1. Fix the guard: check `if (error)` first, then handle null data as a not-found case separately
  2. Use `.maybeSingle()` instead of `.single()` so zero-row results return null data with no error, then branch on data
  3. Validate modelId is a UUID before querying to get a clearer error

Example fix

// before
if (!model) {
  throw new Error(error.message)
}
return model

// after
if (error) {
  throw new Error(`getModelById failed [${error.code}]: ${error.message}`)
}
if (!model) {
  throw new Error(`Model ${modelId} not found`)
}
return model
Defensive patterns

Strategy: type-guard

Validate before calling

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
if (!UUID_RE.test(modelId)) throw new Error(`invalid model id: ${modelId}`)

Type guard

const isModel = (m: unknown): m is Tables<"models"> =>
  typeof m === "object" && m !== null && "id" in m && "user_id" in m

Try / catch

try {
  return await getModelById(modelId)
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e)
  if (msg.includes("PGRST116") || /no rows/i.test(msg)) throw new NotFoundError(`model ${modelId}`)
  throw e
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mckaywrigley/chatbot-ui@81328b61d2 (2026-08-27). Data as JSON: /api/errors/d5f4449f85949a16. Report an issue: GitHub.