Skip to content

fix: continuation loop never stops (stream.switches is never incremented) - #2187

Open
Cadenadb wants to merge 1 commit into
stackblitz-labs:mainfrom
Cadenadb:fix/max-response-segments-loop
Open

fix: continuation loop never stops (stream.switches is never incremented)#2187
Cadenadb wants to merge 1 commit into
stackblitz-labs:mainfrom
Cadenadb:fix/max-response-segments-loop

Conversation

@Cadenadb

@Cadenadb Cadenadb commented Aug 4, 2026

Copy link
Copy Markdown

Bug

When a response is cut off by the model's token limit (finishReason === 'length'), api.chat.ts is supposed to auto-continue at most MAX_RESPONSE_SEGMENTS (2) times, then stop with Cannot continue message: Maximum segments reached.

That cap never triggers, because it checks stream.switches, and SwitchableStream._switches is only incremented inside switchSource() -- a method that api.chat.ts never calls. So stream.switches stays 0 forever, and the continuation branch recurses indefinitely for any model that keeps returning finishReason: 'length'.

Impact

Observed in production: a long chat that grew close to the 128k context cap got stuck making one real LLM call every ~40s, forever -- 10 consecutive identical Reached max token limit (128000): Continuing message (2 switches left) log lines over 8 minutes, no progress, no error surfaced to the UI (it just looks frozen), and real API credits silently consumed on every retry (confirmed against a paid provider).

This isn't provider-specific -- any model/setup that legitimately hits the output token cap on a large response will loop forever instead of stopping at 2 segments as intended.

Fix

Track continuation attempts with a local counter (continuationSegments) that is actually incremented on every continuation, instead of relying on the never-updated stream.switches. Restores the originally intended 2-segment cap.

Minimal, single-file change, no behavior change for the normal (non-looping) path.

…ncremented

SwitchableStream._switches only increments inside switchSource(), which
api.chat.ts never calls. The safety check that's supposed to cap
auto-continuation at MAX_RESPONSE_SEGMENTS (stream.switches >=
MAX_RESPONSE_SEGMENTS) therefore never trips, so a response that keeps
returning finishReason: 'length' triggers an infinite continuation loop
-- one real LLM call every ~40s, forever, silently consuming API credits,
with the UI appearing frozen since nothing ever completes.

Fix: track continuation attempts with a local counter that's actually
incremented on every continuation, restoring the intended 2-segment cap.

Observed in production against DeepSeek (deepseek-chat / deepseek-v4-flash)
on a long-running chat that had grown close to the 128k token context cap:
10 consecutive identical 'Reached max token limit (128000): Continuing
message (2 switches left)' log lines over 8 minutes, message count frozen,
real balance drained on every retry.
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.

1 participant