mckaywrigley/chatbot-ui · warning
File must be less than ${Math.floor(SIZE_LIMIT / 1000000)}MB
Error message
File must be less than ${Math.floor(SIZE_LIMIT / 1000000)}MB What it means
Thrown by uploadFile when the File's byte size exceeds NEXT_PUBLIC_USER_FILE_SIZE_LIMIT (parsed as an integer, defaulting to 10000000 bytes = 10MB). This is a purely client-side guard executed before any network call to Supabase Storage. The template interpolates Math.floor(SIZE_LIMIT / 1000000) so the message shows the limit in whole MB.
Source
Thrown at db/storage/files.ts:17
import { supabase } from "@/lib/supabase/browser-client"
import { toast } from "sonner"
export const uploadFile = async (
file: File,
payload: {
name: string
user_id: string
file_id: string
}
) => {
const SIZE_LIMIT = parseInt(
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
}View on GitHub (pinned to 81328b61d2)
Solutions
- Compress or split the file, or raise NEXT_PUBLIC_USER_FILE_SIZE_LIMIT to an explicit byte value (e.g. '50000000') and rebuild the app.
- Verify the env var is a plain byte count with no unit suffix — '10mb' parseInts to 10 and breaks the check.
- Warn users in the UI before upload by checking file.size against the same limit client-side.
- Keep the Supabase Storage bucket's own size cap in sync if you raise this limit.
Example fix
// before
const SIZE_LIMIT = parseInt(
process.env.NEXT_PUBLIC_USER_FILE_SIZE_LIMIT || "10000000"
)
// after
const SIZE_LIMIT = Number(
process.env.NEXT_PUBLIC_USER_FILE_SIZE_LIMIT || "10000000"
)
if (!Number.isFinite(SIZE_LIMIT) || SIZE_LIMIT <= 0) {
throw new Error("Invalid NEXT_PUBLIC_USER_FILE_SIZE_LIMIT")
} Defensive patterns
Strategy: validation
Validate before calling
const SIZE_LIMIT = Number(process.env.NEXT_PUBLIC_USER_FILE_SIZE_LIMIT || "10000000")
if (file.size > SIZE_LIMIT) {
toast.error(`File too large — max ${Math.floor(SIZE_LIMIT / 1_000_000)}MB`)
// stop before calling uploadFile
} Type guard
const isWithinLimit = (f: File, limit: number): boolean => f.size <= limit && Number.isFinite(limit)
Try / catch
try {
await uploadFile(file, payload)
} catch (e) {
if (e instanceof Error && e.message.startsWith("File must be less than")) {
toast.error(e.message) // user-fixable; no retry needed
} else {
throw e
}
} Prevention
- Validate file.size in the picker UI before submission.
- Keep NEXT_PUBLIC_USER_FILE_SIZE_LIMIT as raw bytes (no 'MB' suffix) and validate it parses to a sane positive number.
- Remember NEXT_PUBLIC_ vars are inlined at build time — rebuild after changing them.
When it happens
Trigger: Passing a file with file.size > SIZE_LIMIT — e.g. an 11MB PDF against the 10MB default; or setting NEXT_PUBLIC_USER_FILE_SIZE_LIMIT to a small value like '1000000' so previously fine files now throw. Because parseInt stops at the first non-digit, a malformed value like '10mb' parses as 10 (bytes), rejecting nearly everything.
Common situations: Env var set as '10MB' or '10 mb' instead of raw bytes; changing the limit per environment but only rebuilding one; large exports/recordings users try to attach; forgetting that NEXT_PUBLIC_ vars are inlined at build time so runtime .env changes have no effect until rebuild.
Related errors
- Image must be less than ${imageSizeLimit / 1000000}MB
- Image must be less than ${imageSizeLimit / 1000000}MB
- Error uploading file
- Error downloading file
AI-assisted analysis of mckaywrigley/chatbot-ui@81328b61d2 (2026-08-27).
Data as JSON: /api/errors/832c0d6884003d77.
Report an issue: GitHub.