diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 38a91000a..dd9c54e22 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -4456,9 +4456,27 @@ const SMART_AUTO_GRAPH_TIMEOUT_MS = 28_000; const SMART_AUTO_FALLBACK_TIMEOUT_MS = 20_000; const SMART_AUTO_IMAGE_SUMMARY_TIMEOUT_MS = 18_000; const DEFAULT_STREAM_KEEPALIVE_INTERVAL_MS = 12_000; +const CHAT_CREATION_LOOKUP_RETRY_DELAYS_MS = [60, 180, 360] as const; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); +async function findChatWithRetry(chatId: string) { + let currentChat = await getChatById({ id: chatId }); + if (currentChat) { + return currentChat; + } + + for (const delayMs of CHAT_CREATION_LOOKUP_RETRY_DELAYS_MS) { + await sleep(delayMs); + currentChat = await getChatById({ id: chatId }); + if (currentChat) { + return currentChat; + } + } + + return null; +} + class OperationTimeoutError extends Error { constructor(operation: string, timeoutMs: number) { super(`${operation} timed out after ${timeoutMs}ms`); @@ -6276,7 +6294,7 @@ export async function POST(request: Request) { visibility: selectedVisibilityType, }); } catch (error) { - const racedChat = await getChatById({ id }); + const racedChat = await findChatWithRetry(id); if (!racedChat) { throw error; } @@ -6291,7 +6309,7 @@ export async function POST(request: Request) { }); } - chat = await getChatById({ id }); + chat = await findChatWithRetry(id); if (!chat) { throw new ChatSDKError("bad_request:database", "Failed to save chat"); } diff --git a/lib/db/queries.ts b/lib/db/queries.ts index 12a2db91e..482a1ec29 100644 --- a/lib/db/queries.ts +++ b/lib/db/queries.ts @@ -168,13 +168,18 @@ export async function saveChat({ visibility: VisibilityType; }) { try { - return await db.insert(chat).values({ - id, - createdAt: new Date(), - userId, - title, - visibility, - }); + return await db + .insert(chat) + .values({ + id, + createdAt: new Date(), + userId, + title, + visibility, + }) + .onConflictDoNothing({ + target: chat.id, + }); } catch (_error) { throw new ChatSDKError("bad_request:database", "Failed to save chat"); }