From 24e3ad47312c22575e5d84d414327470f3217623 Mon Sep 17 00:00:00 2001 From: Recoup Coding Agent Date: Sun, 29 Mar 2026 21:56:23 -0500 Subject: [PATCH 1/2] fix: prevent Vercel Blob upload conflicts on retry (#1606) * fix: prevent Vercel Blob upload conflicts and improve error handling - Add addRandomSuffix and allowOverwrite to blob upload token options, preventing "blob already exists" errors on retry uploads - Use Promise.allSettled for resilient multi-file blob uploads - Surface meaningful error messages when blob uploads fail Co-Authored-By: Paperclip * fix: remove redundant allowOverwrite and surface blob upload errors - Remove allowOverwrite: true (redundant with addRandomSuffix) - Surface rejected blob uploads in the errors array so callers can report partial failures to the user Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: CTO Agent Co-authored-by: Paperclip Co-authored-by: Sweets Sweetman Co-authored-by: Claude Opus 4.6 (1M context) --- app/api/sandbox/upload/route.ts | 1 + lib/sandboxes/uploadSandboxFiles.ts | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/api/sandbox/upload/route.ts b/app/api/sandbox/upload/route.ts index 48f2395c5..2fb52414b 100644 --- a/app/api/sandbox/upload/route.ts +++ b/app/api/sandbox/upload/route.ts @@ -25,6 +25,7 @@ export async function POST(request: Request): Promise { return { maximumSizeInBytes: 100 * 1024 * 1024, // 100MB + addRandomSuffix: true, }; }, onUploadCompleted: async () => {}, diff --git a/lib/sandboxes/uploadSandboxFiles.ts b/lib/sandboxes/uploadSandboxFiles.ts index d0e3f56ca..c7db2d161 100644 --- a/lib/sandboxes/uploadSandboxFiles.ts +++ b/lib/sandboxes/uploadSandboxFiles.ts @@ -36,7 +36,7 @@ export async function uploadSandboxFiles({ path?: string; message?: string; }): Promise<{ uploaded: UploadedFile[]; errors?: string[] }> { - const blobFiles = await Promise.all( + const results = await Promise.allSettled( files.map(async (file) => { const blob = await upload(file.name, file, { access: "public", @@ -47,6 +47,23 @@ export async function uploadSandboxFiles({ }), ); + const blobFiles: { url: string; name: string }[] = []; + const blobErrors: string[] = []; + + results.forEach((r, i) => { + if (r.status === "fulfilled") { + blobFiles.push(r.value); + } else { + blobErrors.push(`${files[i].name}: ${r.reason?.message || "Upload failed"}`); + } + }); + + if (blobFiles.length === 0) { + throw new Error( + blobErrors[0] || "Failed to upload files to temporary storage", + ); + } + const response = await fetch(`${NEW_API_BASE_URL}/api/sandboxes/files`, { method: "POST", headers: { @@ -66,8 +83,10 @@ export async function uploadSandboxFiles({ throw new Error(data.error || "Failed to upload files"); } + const allErrors = [...blobErrors, ...(data.errors || [])]; + return { uploaded: data.uploaded || [], - errors: data.errors, + ...(allErrors.length > 0 && { errors: allErrors }), }; } From c7bd480e91562e402884f447c24c2dd2042c491e Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Mon, 30 Mar 2026 21:00:25 +0530 Subject: [PATCH 2/2] chore: remove unused local room create endpoint --- app/api/room/create/route.tsx | 38 ----------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 app/api/room/create/route.tsx diff --git a/app/api/room/create/route.tsx b/app/api/room/create/route.tsx deleted file mode 100644 index 59adeaf92..000000000 --- a/app/api/room/create/route.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { createRoomWithReport } from "@/lib/supabase/createRoomWithReport"; -import { NextRequest } from "next/server"; - -export async function GET(req: NextRequest) { - const topic = req.nextUrl.searchParams.get("topic"); - const account_id = req.nextUrl.searchParams.get("account_id"); - const report_id = req.nextUrl.searchParams.get("report_id"); - const artist_id = req.nextUrl.searchParams.get("artist_id"); - const chat_id = req.nextUrl.searchParams.get("chat_id"); - - if (!topic || !account_id) { - return Response.json( - { message: "Missing required parameters" }, - { status: 400 } - ); - } - - try { - const result = await createRoomWithReport({ - account_id, - topic, - report_id: report_id || undefined, - artist_id: artist_id || undefined, - chat_id: chat_id || undefined, - }); - - return Response.json(result, { status: 200 }); - } catch (error) { - console.error("Error in /api/room/create:", error); - const message = - error instanceof Error ? error.message : "Failed to create room"; - return Response.json({ message }, { status: 400 }); - } -} - -export const dynamic = "force-dynamic"; -export const fetchCache = "force-no-store"; -export const revalidate = 0;