mckaywrigley/chatbot-ui · warning · Error

Message not found

Error message

Message not found

What it means

A domain-level 'Message not found' error thrown when getMessageById's .single() select returns null. Unlike the supabase errors elsewhere, this is the app's own message: either the message id doesn't exist, was deleted, or is hidden by RLS for the current user (which makes an existing row look missing).

Source

Thrown at db/messages.ts:12

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

export const getMessageById = async (messageId: string) => {
  const { data: message } = await supabase
    .from("messages")
    .select("*")
    .eq("id", messageId)
    .single()

  if (!message) {
    throw new Error("Message not found")
  }

  return message
}

export const getMessagesByChatId = async (chatId: string) => {
  const { data: messages } = await supabase
    .from("messages")
    .select("*")
    .eq("chat_id", chatId)

  if (!messages) {
    throw new Error("Messages not found")
  }

  return messages
}

View on GitHub (pinned to 81328b61d2)

Solutions

  1. Treat this as an expected 404: catch it and show 'message unavailable' instead of an error boundary
  2. Verify the message id exists in the messages table for that user before calling
  3. Check RLS SELECT policies on messages if the message should be visible
  4. Invalidate cached message ids on account/workspace switch

Example fix

// before
try {
  const message = await getMessageById(messageId)
} catch (e) { /* generic error */ }

// after
try {
  const message = await getMessageById(messageId)
} catch (e) {
  if (e instanceof Error && e.message === "Message not found") {
    return notFoundResponse(messageId)
  }
  throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

const { data } = await supabase.from("messages").select("id").eq("id", messageId).maybeSingle()
if (!data.data) return notFoundResponse()

Type guard

function isMessageNotFound(e: unknown): e is Error {
  return e instanceof Error && e.message === "Message not found"
}

Try / catch

try { return await getMessageById(messageId) }
catch (e) {
  if (isMessageNotFound(e)) return notFound()
  throw e
}

Prevention

When it happens

Trigger: Calling getMessageById with a deleted/nonexistent id, a message belonging to another user's chat under RLS, or an id held in stale client state after switching workspaces/accounts.

Common situations: Deep links to removed messages, retrying an action after the message was deleted in another session, RLS chat policies hiding rows, switching accounts without clearing cached message ids.

Related errors


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