Skip to content

fix(dashboard): prevent quick chat init race condition and infinite retry loop#45

Merged
gsxdsm merged 2 commits intoRunfusion:mainfrom
timothyjlaurent:fix/quick-chat-init-race-condition
May 6, 2026
Merged

fix(dashboard): prevent quick chat init race condition and infinite retry loop#45
gsxdsm merged 2 commits intoRunfusion:mainfrom
timothyjlaurent:fix/quick-chat-init-race-condition

Conversation

@timothyjlaurent
Copy link
Copy Markdown
Contributor

@timothyjlaurent timothyjlaurent commented May 5, 2026

Summary

  • Fix race condition in handleCreateFreshSession where setting chatMode/selectedAgentId before startFreshSession triggered the session-init useEffect, causing it to resume the old session instead of creating a new one
  • Fix infinite "Failed to initialize chat" toast loop by capping retries at 3 (initRetryCountRef)
  • Fix cascading re-renders where switchSession got a new identity on every activeSession change, re-triggering the consumer's useEffect. Now reads activeSession from a ref

Root Cause

Three interacting bugs in useQuickChat / QuickChatFAB:

  1. Race condition: handleCreateFreshSession called setChatMode("agent") + setSelectedAgentId(agentId) before startFreshSession(). These state changes triggered the session-init useEffect (line 1184), which called switchSession()initializeSession()fetchResumeChatSession() → found and loaded the OLD session. The explicit fresh creation lost the race.

  2. Infinite retry loop: The shouldRetrySessionInit check re-triggered switchSession whenever activeSession was null and sessionsLoading was false. If the API call failed, this created an unbounded loop of "Failed to initialize chat" toasts.

  3. Cascading re-renders: switchSession had activeSession in its dependency array, and the useEffect depended on switchSession. Every activeSession change → new switchSession identity → useEffect re-runs.

Test plan

  • All 44 existing unit tests pass (25 useQuickChat + 19 QuickChatFAB)
  • Manual QA: open quick chat → session resumes correctly
  • Manual QA: create new chat with agent → creates fresh session (not old one)
  • Manual QA: create second fresh session → works, shows blank slate
  • Manual QA: close & reopen → resumes latest session
  • Manual QA: switch sessions via dropdown → works
  • Manual QA: no "failed to initialize" toast spam across all scenarios
  • Manual QA: input is enabled and typeable after all operations

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added an opt-out control to prevent automatic Quick Chat session initialization when switching targets.
  • Bug Fixes

    • Fixed race conditions in Quick Chat session initialization when switching chat targets.
    • Improved error handling with capped retries to prevent error-message spam during session setup.
  • Refactor

    • Optimized session state and initialization logic for improved stability and performance.
  • Tests

    • Added extensive regression and recovery tests covering initialization retries, skip-flag behavior, session switching, and streaming recovery.

…etry loop

Three interacting bugs caused "Failed to initialize chat" toast spam and
prevented fresh session creation:

1. Race condition in handleCreateFreshSession — setting chatMode/
   selectedAgentId before startFreshSession triggered the session-init
   useEffect, which called switchSession and resumed the old session
   instead of creating a new one. Fixed with skipNextSessionInitRef.

2. Infinite retry loop — shouldRetrySessionInit retried indefinitely
   when initializeSession failed, producing unbounded toast spam.
   Fixed with a 3-retry cap (initRetryCountRef).

3. Cascading re-renders — switchSession depended on activeSession in
   its closure, getting a new identity on every state change and
   re-triggering the consumer's useEffect. Fixed by reading
   activeSession from a ref instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 5, 2026

📝 Walkthrough

Walkthrough

Adds a ref-based opt-out (skipNextSessionInitRef) to useQuickChat to prevent automatic session initialization races, moves session coordination into refs, caps init-retry to 3 with conditional toasts, and wires the flag into the QuickChat FAB effect to skip automatic init when explicit fresh-session creation is in progress.

Changes

Session initialization & race prevention

Layer / File(s) Summary
Public Interface
packages/dashboard/app/hooks/useQuickChat.ts
Adds skipNextSessionInitRef: React.MutableRefObject<boolean> to UseQuickChatReturn and exposes it in the hook return.
Internal refs & constants
packages/dashboard/app/hooks/useQuickChat.ts
Introduces activeSessionRef, initRetryCountRef, skipNextSessionInitRef (internal), and INIT_MAX_RETRIES = 3; syncs activeSessionRef.current with activeSession.
Initialization logic & error handling
packages/dashboard/app/hooks/useQuickChat.ts
initializeSession increments initRetryCountRef on failure, toasts only while <= INIT_MAX_RETRIES, and resets counter on success.
Fresh-session flow & switch logic
packages/dashboard/app/hooks/useQuickChat.ts
startFreshSession sets skipNextSessionInitRef.current = true and resets retry count before creating a fresh session; clears the flag after. switchSession uses refs (e.g., activeSessionRef.current) to avoid cascading re-renders and updated dependency array.
Component wiring
packages/dashboard/app/components/QuickChatFAB.tsx
Destructures skipNextSessionInitRef from useQuickChat, adds a guard in the session-init useEffect to early-return when flag is set (also updates prevSessionTargetRef), and includes the ref in the effect dependencies.
Tests
packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts
Adds regression suites covering init-retry limit and toast capping, retry counter reset on success, startFreshSession skip-flag behavior, session-switch deduplication using refs, and streaming-state recovery tests.
sequenceDiagram
    participant UI as QuickChatFAB (Component)
    participant Hook as useQuickChat (Hook)
    participant API as Chat API / initializeSession
    participant Toast as Toast System

    UI->>Hook: call useQuickChat(projectId, addToast)
    UI->>Hook: invoke startFreshSession()
    Hook->>Hook: set skipNextSessionInitRef.current = true\nreset initRetryCountRef
    Hook->>API: create new session (explicit)
    API-->>Hook: session created / error
    alt success
        Hook->>Hook: reset initRetryCountRef\nskipNextSessionInitRef.current = false
        Hook->>UI: return active session
    else failure
        Hook->>Hook: initRetryCountRef++
        alt within retries
            Hook->>Toast: show error toast
        end
        Hook->>Hook: skipNextSessionInitRef.current = false
    end

    Note right of Hook: separate automatic init effect\nobserves skipNextSessionInitRef to avoid racing
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • gsxdsm

Poem

A rabbit nudges refs with nimble paws,
Skipping starts and dodging racing jaws.
Retries are counted, toasts kept tame,
Fresh sessions hop in without a flame. 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main changes: preventing a race condition and avoiding an infinite retry loop in quick chat initialization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 5, 2026

Greptile Summary

This PR addresses three interacting bugs in useQuickChat/QuickChatFAB: a race condition where state changes in handleCreateFreshSession triggered the session-init effect before the fresh session was created, infinite "Failed to initialize chat" toast spam, and cascading re-renders caused by switchSession holding a stale reference to activeSession.

  • Introduces skipNextSessionInitRef (set synchronously at the top of startFreshSession, cleared in finally) so the consuming component's session-init useEffect can short-circuit while an explicit fresh-session creation is in flight, eliminating the race condition.
  • Adds activeSessionRef mirroring activeSession and removes activeSession from switchSession's dependency array, so switchSession no longer gets a new identity on every active-session change, preventing the cascading re-render loop.
  • Caps consecutive addToast calls at 3 via initRetryCountRef, preventing toast spam on repeated failures \u2014 though the underlying shouldRetrySessionInit loop in QuickChatFAB continues to fire switchSession and hit the API after the cap is reached (flagged in an earlier review thread).

Confidence Score: 3/5

The race condition and cascading re-render fixes are mechanically sound, but two prior review findings remain unaddressed: the shouldRetrySessionInit loop continues hitting the API without bound after the toast cap kicks in, and initRetryCountRef is not reset when switching to a new session target.

The skip-flag and ref-mirror changes are correct and the synchronous flag placement before any awaits ensures the race window is closed. However, the retry-cap only gates toasts — the actual API loop driven by shouldRetrySessionInit in QuickChatFAB has no corresponding bail-out, so repeated network failures still hammer the endpoint indefinitely. Additionally, the retry counter persisting across target switches means a user who accumulates failures on agent A then switches to agent B will receive no error feedback for agent B failures. Both were flagged in earlier rounds and remain in the current code.

packages/dashboard/app/hooks/useQuickChat.ts — the initRetryCountRef logic and its interaction with shouldRetrySessionInit in QuickChatFAB need a coordinated fix to stop unbounded API calls and properly scope the counter per session target.

Important Files Changed

Filename Overview
packages/dashboard/app/hooks/useQuickChat.ts Introduces skipNextSessionInitRef flag, activeSessionRef mirror, and initRetryCountRef cap to fix three interacting bugs; two previously-flagged issues remain: the retry cap only suppresses toasts (not API calls) and the counter is not reset when switching to a new session target.
packages/dashboard/app/components/QuickChatFAB.tsx Consumes skipNextSessionInitRef from the hook to gate the session-init useEffect, correctly preventing the race with startFreshSession; the shouldRetrySessionInit loop remains unbounded at the API level.
packages/dashboard/app/hooks/tests/useQuickChat.test.ts Adds 198 lines of regression tests covering toast-cap, skip-flag lifecycle, and cascading-re-render fix; the toast-cap test enshrines counter persistence across targets as expected behavior, and the skip-flag test cannot observe the flag mid-execution to verify race prevention.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant FAB as QuickChatFAB
    participant Hook as useQuickChat
    participant API as API

    U->>FAB: Click "New Chat" (agent)
    FAB->>FAB: setChatMode / setSelectedAgentId
    FAB->>Hook: startFreshSession(agentId)
    Note over Hook: skipNextSessionInitRef = true (sync)
    Hook->>Hook: setActiveSession(null), setSessionsLoading(true)

    Note over FAB: React flushes — session-init useEffect fires
    FAB->>FAB: skipNextSessionInitRef.current? true → skip, record target as seen

    Hook->>API: createSessionForTarget(target)
    API-->>Hook: newSession
    Hook->>Hook: setActiveSession(newSession)
    Note over Hook: finally: skipNextSessionInitRef = false, setSessionsLoading(false)

    Note over FAB: React flushes — useEffect fires again
    FAB->>FAB: sessionTargetKey === prev, activeSession set → early return

    Note over FAB,Hook: Normal switchSession path
    FAB->>Hook: switchSession(agentId)
    Hook->>Hook: isSameSession? reads activeSessionRef.current
    alt New target
        Hook->>Hook: setActiveSession(null)
        Hook->>API: fetchResumeChatSession
        API-->>Hook: session or null
        Hook->>Hook: setActiveSession(result)
        Note over Hook: initRetryCountRef++ on failure, toast if <= 3
    else Same target
        Hook->>API: fetchChatMessages (reload only)
    end
Loading

Reviews (2): Last reviewed commit: "test(dashboard): add regression tests fo..." | Re-trigger Greptile

Comment on lines 308 to 319
} catch (err) {
console.error("[useQuickChat] Failed to initialize session:", err);
addToast?.("Failed to initialize chat", "error");
// Only show the toast while under the retry limit — once the limit
// is reached the user has already seen the warning and further
// toasts just create noise.
initRetryCountRef.current += 1;
if (initRetryCountRef.current <= INIT_MAX_RETRIES) {
addToast?.("Failed to initialize chat", "error");
}
} finally {
setSessionsLoading(false);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Retry cap silences toasts but not API calls

initRetryCountRef guards the addToast call, but shouldRetrySessionInit in QuickChatFAB has no corresponding guard. After 3 failures activeSession is still null and sessionsLoading goes false, so the useEffect keeps triggering switchSessioninitializeSession in an unbounded loop — just without user-visible toasts. The fix prevents toast spam but leaves the actual infinite API call loop in place. initializeSession should bail early when initRetryCountRef.current >= INIT_MAX_RETRIES, or the component's shouldRetrySessionInit condition must receive an exposed ref to gate retries entirely.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/dashboard/app/components/QuickChatFAB.tsx (1)

1209-1237: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Retry cap still doesn't stop the init loop.

shouldRetrySessionInit only checks !activeSession && !sessionsLoading, so every failed init schedules another switchSession/startModelChat as soon as loading flips back to false. The new counter only suppresses the toast; the backend request loop is still unbounded.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/components/QuickChatFAB.tsx` around lines 1209 - 1237,
The retry logic lets failed inits loop because shouldRetrySessionInit only
checks activeSession and sessionsLoading; add a retry-cap ref (e.g.,
sessionInitRetryRef) and MAX_SESSION_INIT_RETRIES constant, increment the ref
each time you attempt startModelChat or switchSession, reset it when a session
becomes active or when sessionTargetKey changes, and check
sessionInitRetryRef.current < MAX_SESSION_INIT_RETRIES before invoking
startModelChat/switchSession (and set prevSessionTargetRef.current to
sessionTargetKey or flip skipNextSessionInitRef when cap reached) so no further
backend requests are triggered after the max attempts; update the useEffect
condition to include this retry-cap check alongside shouldRetrySessionInit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/dashboard/app/hooks/useQuickChat.ts`:
- Around line 62-68: Update the public API type for skipNextSessionInitRef from
React.MutableRefObject<boolean> to React.RefObject<boolean> in the useQuickChat
hook and any exported types/interfaces that reference it (e.g., the useQuickChat
return type or related props), ensuring the signature now reads
skipNextSessionInitRef: React.RefObject<boolean> so it matches React 19's useRef
typing; adjust any import/exports or type aliases that reference
skipNextSessionInitRef to keep types consistent.

---

Outside diff comments:
In `@packages/dashboard/app/components/QuickChatFAB.tsx`:
- Around line 1209-1237: The retry logic lets failed inits loop because
shouldRetrySessionInit only checks activeSession and sessionsLoading; add a
retry-cap ref (e.g., sessionInitRetryRef) and MAX_SESSION_INIT_RETRIES constant,
increment the ref each time you attempt startModelChat or switchSession, reset
it when a session becomes active or when sessionTargetKey changes, and check
sessionInitRetryRef.current < MAX_SESSION_INIT_RETRIES before invoking
startModelChat/switchSession (and set prevSessionTargetRef.current to
sessionTargetKey or flip skipNextSessionInitRef when cap reached) so no further
backend requests are triggered after the max attempts; update the useEffect
condition to include this retry-cap check alongside shouldRetrySessionInit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e991701e-cf84-499c-bde2-8a57bb524e0d

📥 Commits

Reviewing files that changed from the base of the PR and between 58a0eff and 5e5b400.

📒 Files selected for processing (2)
  • packages/dashboard/app/components/QuickChatFAB.tsx
  • packages/dashboard/app/hooks/useQuickChat.ts

Comment on lines +62 to +68
/**
* When true, the consuming component's session-init useEffect should
* skip its automatic switchSession call. Set during startFreshSession
* to prevent the useEffect from racing with an explicit fresh-session
* creation.
*/
skipNextSessionInitRef: React.MutableRefObject<boolean>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In React 19 / @types/react19, isMutableRefObjectstill exported foruseRef, or should RefObject be used instead?

💡 Result:

In React 19 with @types/react 19, MutableRefObject is no longer the type you should rely on for useRef. useRef is typed to return RefObject<T> (and “all refs are mutable” in the React 19 type model), so you should use RefObject<T> (or the more general Ref<T>/React.Ref<T> when typing the ref prop) instead of MutableRefObject<T> for new code.[1][2][3] Practical guidance: 1) For your own useRef variable: prefer const x = useRef<T>(...) and let TypeScript infer RefObject<T>; don’t annotate as MutableRefObject<T>.[1][2] 2) For a component prop that receives a ref (React 19 “ref as prop”): type it as ref?: React.Ref<T> (or ref?: React.RefObject<T> if you specifically want an object ref). Using React.Ref<T> is the generally correct choice for a prop that may receive either callback refs or object refs.[4] Answering your question directly: MutableRefObject may still exist for backwards compatibility, but in the React 19 type system it’s deprecated/merged away conceptually—useRef returns RefObject, so you should use RefObject<T> rather than MutableRefObject<T>.[1][2]

Citations:


Change React.MutableRefObject<boolean> to React.RefObject<boolean>

React 19's TypeScript type system no longer uses MutableRefObject for useRef returns; it uses RefObject<T> instead. Update the public API signature from skipNextSessionInitRef: React.MutableRefObject<boolean> to skipNextSessionInitRef: React.RefObject<boolean>.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/hooks/useQuickChat.ts` around lines 62 - 68, Update
the public API type for skipNextSessionInitRef from
React.MutableRefObject<boolean> to React.RefObject<boolean> in the useQuickChat
hook and any exported types/interfaces that reference it (e.g., the useQuickChat
return type or related props), ensuring the signature now reads
skipNextSessionInitRef: React.RefObject<boolean> so it matches React 19's useRef
typing; adjust any import/exports or type aliases that reference
skipNextSessionInitRef to keep types consistent.

Six new tests covering the three bugs fixed in the previous commit:

- Retry limit: stops showing toasts after 3 consecutive failures,
  resets counter on success
- Skip flag: startFreshSession sets/clears skipNextSessionInitRef,
  creates new session even when existing one exists
- Ref stability: switchSession reads activeSession from ref so it
  correctly detects "same session" and skips re-initialization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts (2)

1007-1024: ⚡ Quick win

Add a direct assertion that switchSession callback identity stays stable.

The comment explains identity stability as the core fix, but this test only checks API side effects. Add a toBe reference check before/after activeSession updates to lock the regression down.

Proposed assertion diff
     const { result } = renderHook(() => useQuickChat("proj-123"));
+    const initialSwitchSession = result.current.switchSession;

     await act(async () => {
       await result.current.switchSession("agent-001");
     });

     expect(result.current.activeSession).not.toBeNull();
+    expect(result.current.switchSession).toBe(initialSwitchSession);
@@
     await act(async () => {
       await result.current.switchSession("agent-001");
     });
+    expect(result.current.switchSession).toBe(initialSwitchSession);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts` around lines
1007 - 1024, Capture the switchSession callback reference from result.current
(e.g., const prevSwitch = result.current.switchSession) before calling
switchSession again, then after awaiting the second switchSession call assert
the identity is unchanged using
expect(result.current.switchSession).toBe(prevSwitch); this locks the regression
by verifying the callback's referential stability in addition to the existing
API-call assertions (use the existing result.current.switchSession and
activeSession-related setup in the test).

932-956: ⚡ Quick win

The skip-flag regression test never proves the flag is true while startFreshSession is in flight.

At Line 950-Line 952, the call is fully awaited, so only the final cleared state is observed. A regression where skipNextSessionInitRef is never set would still pass.

Proposed test-tightening diff
-      // During startFreshSession — the flag is set then cleared in finally
-      await act(async () => {
-        await result.current.startFreshSession();
-      });
+      // Hold session creation to observe in-flight state
+      let resolveCreate: ((value: { session: ChatSession }) => void) | undefined;
+      mockCreateChatSession.mockImplementationOnce(
+        () =>
+          new Promise<{ session: ChatSession }>((resolve) => {
+            resolveCreate = resolve;
+          }),
+      );
+
+      let freshPromise: Promise<void> | undefined;
+      act(() => {
+        freshPromise = result.current.startFreshSession();
+      });
+
+      await waitFor(() => {
+        expect(result.current.skipNextSessionInitRef.current).toBe(true);
+      });
+
+      await act(async () => {
+        resolveCreate?.({ session: freshSession });
+        await freshPromise;
+      });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts` around lines 932
- 956, The test doesn't observe skipNextSessionInitRef while startFreshSession
is running because startFreshSession is fully awaited; modify the test in
useQuickChat.test.ts to stub/mock the async call inside startFreshSession (e.g.,
mockCreateChatSession or whichever network call startFreshSession awaits) to
return a controllable promise, call result.current.startFreshSession() without
awaiting its resolution, assert that
result.current.skipNextSessionInitRef.current is true while that promise is
still pending, then resolve the promise and await completion and assert the flag
is cleared and activeSession is "session-fresh"; reference startFreshSession,
switchSession, skipNextSessionInitRef, and mockCreateChatSession (or the
specific mocked fetch used by startFreshSession) to implement the controllable
promise.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts`:
- Around line 1007-1024: Capture the switchSession callback reference from
result.current (e.g., const prevSwitch = result.current.switchSession) before
calling switchSession again, then after awaiting the second switchSession call
assert the identity is unchanged using
expect(result.current.switchSession).toBe(prevSwitch); this locks the regression
by verifying the callback's referential stability in addition to the existing
API-call assertions (use the existing result.current.switchSession and
activeSession-related setup in the test).
- Around line 932-956: The test doesn't observe skipNextSessionInitRef while
startFreshSession is running because startFreshSession is fully awaited; modify
the test in useQuickChat.test.ts to stub/mock the async call inside
startFreshSession (e.g., mockCreateChatSession or whichever network call
startFreshSession awaits) to return a controllable promise, call
result.current.startFreshSession() without awaiting its resolution, assert that
result.current.skipNextSessionInitRef.current is true while that promise is
still pending, then resolve the promise and await completion and assert the flag
is cleared and activeSession is "session-fresh"; reference startFreshSession,
switchSession, skipNextSessionInitRef, and mockCreateChatSession (or the
specific mocked fetch used by startFreshSession) to implement the controllable
promise.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 419a28dd-ebc1-4c09-a22f-5f3999a0dc8c

📥 Commits

Reviewing files that changed from the base of the PR and between 5e5b400 and 2746015.

📒 Files selected for processing (1)
  • packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts

@gsxdsm gsxdsm merged commit 21bedd8 into Runfusion:main May 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants