Skip to content

Commit 12cfa0d

Browse files
fix(react-hooks): prevent onComplete from firing prematurely when stream disconnects
The onComplete callback in useRealtimeRun and useRealtimeRunWithStreams was firing whenever the SSE stream ended, regardless of whether the run had actually completed. This caused issues in self-hosted environments where reverse proxies (like Traefik) may close idle connections. The fix changes the condition from checking `run` to checking `run?.finishedAt`, ensuring onComplete only fires when the run has actually reached a terminal state. Fixes #2856 Co-authored-by: nicktrn <nicktrn@users.noreply.github.com>
1 parent a8024af commit 12cfa0d

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

packages/react-hooks/src/hooks/useRealtime.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ export function useRealtimeRun<TTask extends AnyTask>(
149149
const hasCalledOnCompleteRef = useRef(false);
150150

151151
// Effect to handle onComplete callback
152+
// Only call onComplete when the run has actually finished (has finishedAt),
153+
// not just when the subscription stream ends (which can happen due to network issues)
152154
useEffect(() => {
153-
if (isComplete && run && options?.onComplete && !hasCalledOnCompleteRef.current) {
155+
if (isComplete && run?.finishedAt && options?.onComplete && !hasCalledOnCompleteRef.current) {
154156
options.onComplete(run, error);
155157
hasCalledOnCompleteRef.current = true;
156158
}
@@ -313,8 +315,10 @@ export function useRealtimeRunWithStreams<
313315
const hasCalledOnCompleteRef = useRef(false);
314316

315317
// Effect to handle onComplete callback
318+
// Only call onComplete when the run has actually finished (has finishedAt),
319+
// not just when the subscription stream ends (which can happen due to network issues)
316320
useEffect(() => {
317-
if (isComplete && run && options?.onComplete && !hasCalledOnCompleteRef.current) {
321+
if (isComplete && run?.finishedAt && options?.onComplete && !hasCalledOnCompleteRef.current) {
318322
options.onComplete(run, error);
319323
hasCalledOnCompleteRef.current = true;
320324
}

0 commit comments

Comments
 (0)