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