From be37d543c3f5c00dc9a495f2d6138ef397f3f840 Mon Sep 17 00:00:00 2001 From: user Date: Mon, 15 Jun 2026 15:46:25 -0400 Subject: [PATCH] fix(frontend): restore chat history when returning to a session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace async params.then() + useState pattern with synchronous React.use(params) so projectName and sessionName are available from the first render. The previous pattern left both values as empty strings on mount, causing the AG-UI EventSource connection to be deferred until a second render cycle. On fast re-navigation this race could result in historical SSE events being missed and chat history not rendering. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../[name]/sessions/[sessionName]/page.tsx | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx b/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx index 31357837ce..60ab551bb6 100755 --- a/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx +++ b/components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect, useMemo, useRef, useCallback } from "react"; +import { use, useState, useEffect, useMemo, useRef, useCallback } from "react"; import { Loader2, PanelRight, @@ -117,9 +117,15 @@ export default function ProjectSessionDetailPage({ }) { const router = useRouter(); const queryClient = useQueryClient(); - const [projectName, setProjectName] = useState(""); - const [sessionName, setSessionName] = useState(""); - const [backHref, setBackHref] = useState(null); + const { name: projectName, sessionName } = use(params); + const backHref = useMemo(() => { + if (typeof window !== "undefined") { + try { + return new URL(window.location.href).searchParams.get("backHref"); + } catch {} + } + return null; + }, []); const [contextModalOpen, setContextModalOpen] = useState(false); const [uploadModalOpen, setUploadModalOpen] = useState(false); const [repoChanging, setRepoChanging] = useState(false); @@ -148,18 +154,6 @@ export default function ProjectSessionDetailPage({ const [customWorkflowDialogOpen, setCustomWorkflowDialogOpen] = useState(false); - // Extract params - useEffect(() => { - params.then(({ name, sessionName: sName }) => { - setProjectName(name); - setSessionName(sName); - try { - const url = new URL(window.location.href); - setBackHref(url.searchParams.get("backHref")); - } catch {} - }); - }, [params]); - // Session queue hook (localStorage-backed) const sessionQueue = useSessionQueue(projectName, sessionName); @@ -208,8 +202,8 @@ export default function ProjectSessionDetailPage({ // Note: autoConnect is intentionally false to avoid SSR hydration mismatch // Connection is triggered manually in useEffect after client hydration const aguiStream = useAGUIStream({ - projectName: projectName || "", - sessionName: sessionName || "", + projectName, + sessionName, autoConnect: false, // Manual connection after hydration onError: (err) => { console.error("AG-UI stream error:", err)