Summary
Opening a chat that lives in a different workspace (e.g. clicking it in the sidebar) renders the chat twice: it first opens in the current (wrong) workspace, then re-renders in the correct workspace once the switch completes. Visible as a double-load / flash of the chat window on every cross-workspace navigation.
Steps to reproduce
- Open a chat in workspace A.
- In the sidebar, click a chat that belongs to workspace B.
- The chat window loads, briefly against workspace A, then loads again under workspace B.
Expected
A single render: switch to workspace B, then open the chat in B.
Root cause
In src/routes/+page.svelte, the URL-driven workspace effect both reads and writes lastLoadedPath, which is $state:
let lastLoadedPath = $state<string | null>(null);
$effect(() => {
const workspacePath = $page.url.searchParams.get('workspace');
...
if (workspacePath && workspacePath !== lastLoadedPath) {
lastLoadedPath = workspacePath; // (1) synchronous write to $state
loadWorkspace(workspacePath).then(async () => {
...
processIntentParams(); // (3) correct: runs after load
});
} else if (workspacePath && workspacePath === lastLoadedPath) {
processIntentParams(); // (2) runs immediately
}
...
});
Writing lastLoadedPath at (1) re-triggers the effect synchronously (it's reactive state the effect reads). On that re-run workspacePath === lastLoadedPath, so branch (2) calls processIntentParams() immediately — but loadWorkspace() from the first run is still in flight, so currentWorkspace is still the old workspace. The openChat intent is therefore applied against the wrong workspace (render #1). When loadWorkspace() resolves, the workspace switches and (3) opens the chat again in the correct workspace (render #2).
Suggested fix
Only process intents in the immediate branch when the target workspace is actually current; otherwise let the in-flight loadWorkspace().then() handle it:
} else if (workspacePath && workspacePath === lastLoadedPath) {
if (get(currentWorkspace)?.path === workspacePath) processIntentParams();
}
This preserves the fast path for same-workspace navigation (chat-to-chat within the current workspace) while preventing intents from being applied against a stale workspace during a cross-workspace switch. Single render in all cases.
(Making lastLoadedPath a plain let instead of $state also resolves it, by removing the spurious self-retrigger — but the guard is the smaller, more targeted change.)
Summary
Opening a chat that lives in a different workspace (e.g. clicking it in the sidebar) renders the chat twice: it first opens in the current (wrong) workspace, then re-renders in the correct workspace once the switch completes. Visible as a double-load / flash of the chat window on every cross-workspace navigation.
Steps to reproduce
Expected
A single render: switch to workspace B, then open the chat in B.
Root cause
In
src/routes/+page.svelte, the URL-driven workspace effect both reads and writeslastLoadedPath, which is$state:Writing
lastLoadedPathat (1) re-triggers the effect synchronously (it's reactive state the effect reads). On that re-runworkspacePath === lastLoadedPath, so branch (2) callsprocessIntentParams()immediately — butloadWorkspace()from the first run is still in flight, socurrentWorkspaceis still the old workspace. TheopenChatintent is therefore applied against the wrong workspace (render #1). WhenloadWorkspace()resolves, the workspace switches and (3) opens the chat again in the correct workspace (render #2).Suggested fix
Only process intents in the immediate branch when the target workspace is actually current; otherwise let the in-flight
loadWorkspace().then()handle it:This preserves the fast path for same-workspace navigation (chat-to-chat within the current workspace) while preventing intents from being applied against a stale workspace during a cross-workspace switch. Single render in all cases.
(Making
lastLoadedPatha plainletinstead of$statealso resolves it, by removing the spurious self-retrigger — but the guard is the smaller, more targeted change.)