mckaywrigley/chatbot-ui · error

Error uploading file

Error message

Error uploading file

What it means

Thrown by uploadFile when supabase.storage.from("files").upload(...) with upsert: true returns an error. Supabase Storage reports bucket-not-found, RLS policy violations, duplicate-object conflicts, or payload-too-large through the returned error object, which this code flattens into a generic message. The upload path is base64(file_id) nested under user_id, so policy matching depends on that folder layout.

Source

Thrown at db/storage/files.ts:31

    process.env.NEXT_PUBLIC_USER_FILE_SIZE_LIMIT || "10000000"
  )

  if (file.size > SIZE_LIMIT) {
    throw new Error(
      `File must be less than ${Math.floor(SIZE_LIMIT / 1000000)}MB`
    )
  }

  const filePath = `${payload.user_id}/${Buffer.from(payload.file_id).toString("base64")}`

  const { error } = await supabase.storage
    .from("files")
    .upload(filePath, file, {
      upsert: true
    })

  if (error) {
    throw new Error("Error uploading file")
  }

  return filePath
}

export const deleteFileFromStorage = async (filePath: string) => {
  const { error } = await supabase.storage.from("files").remove([filePath])

  if (error) {
    toast.error("Failed to remove file!")
    return
  }
}

export const getFileFromStorage = async (filePath: string) => {
  const { data, error } = await supabase.storage
    .from("files")
    .createSignedUrl(filePath, 60 * 60 * 24) // 24hrs

View on GitHub (pinned to 81328b61d2)

Solutions

  1. Log the returned error — error.message distinguishes 'Bucket not found' from 'row-level security' from 'Duplicate'.
  2. Ensure the 'files' bucket exists and has INSERT plus UPDATE policies allowing auth.uid() = (storage.foldername(name))[1].
  3. Confirm a valid authenticated session exists before upload (supabase.auth.getSession()) and refresh if expired.
  4. Double-check NEXT_PUBLIC_SUPABASE_URL/ANON_KEY for the environment performing the upload.

Example fix

// before
if (error) {
  throw new Error("Error uploading file")
}

// after
if (error) {
  throw new Error(`Error uploading file: ${error.message}`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

const { data: session } = await supabase.auth.getSession()
if (!session.session) throw new Error("Authentication required to upload files")

Type guard

const isFileUploadCandidate = (f: File): boolean =>
  f.size > 0 && f.size <= Number(process.env.NEXT_PUBLIC_USER_FILE_SIZE_LIMIT || 1e7)

Try / catch

try {
  const path = await uploadFile(file, payload)
} catch (e) {
  if (e instanceof Error && e.message === "Error uploading file") {
    toast.error("Upload failed — check your connection and try again.")
  } else { throw e }
}

Prevention

When it happens

Trigger: Uploading a file when the 'files' bucket is absent; the authenticated user's JWT failing an INSERT/UPDATE policy on files/user_id/*; expired Supabase session (anon role can't insert); wrong project env vars; or a file exactly at the limit hitting the server's object size cap.

Common situations: Fresh environment missing the 'files' bucket; storage policies written for a different folder scheme than user_id/base64(file_id); token refresh not wired into the browser client; .env.local differing between dev and deployed builds.

Related errors


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