continuedev/continue · error · Error

Stream was closed before any data was received. Try again. (

Error message

Stream was closed before any data was received. Try again. (Premature Close)

What it means

The underlying stream emitted a premature close event before any chunk arrived (chunks === 0), so the generator throws with a 'Try again' hint — transient connection issues are the expected cause.

Source

Thrown at packages/fetch/src/stream.ts:61

      const nodeStream = response.body as unknown as NodeJS.ReadableStream;
      for await (const chunk of toAsyncIterable(nodeStream)) {
        yield decoder.decode(chunk, { stream: true });
        chunks++;
      }
    }
  } catch (e) {
    if (e instanceof Error) {
      if (e.name.startsWith("AbortError")) {
        return; // In case of client-side cancellation, just return
      }
      if (e.message.toLowerCase().includes("premature close")) {
        // Premature close can happen for various reasons, including:
        // - Malformed chunks of data received from the server
        // - The server closed the connection before sending the complete response
        // - Long delays from the server during streaming
        // - 'Keep alive' header being used in combination with an http agent and a set, low number of maxSockets
        if (chunks === 0) {
          throw new Error(
            "Stream was closed before any data was received. Try again. (Premature Close)",
          );
        } else {
          throw new Error(
            "The response was cancelled mid-stream. Try again. (Premature Close).",
          );
        }
      }
    }
    throw e;
  }
}

// Export for testing purposes
export function parseDataLine(line: string): any {
  const json = line.startsWith("data: ")
    ? line.slice("data: ".length)
    : line.slice("data:".length);

View on GitHub (pinned to 5522c6f44c)

Solutions

  1. Retry the request — the message itself recommends it; use 2-3 attempts with backoff
  2. Increase agent maxSockets or disable keep-alive for streaming requests
  3. Raise proxy/LB idle timeouts if you control them
  4. Reduce request latency (shorter prompts, streaming sooner) to avoid idle cutoffs

Example fix

// before
const data = await collectStream(streamSse(response));

// after
async function withRetry(fn, n = 3) { for (let i = 0; ; i++) { try { return await fn(); } catch (e) { if (i === n - 1 || !/Premature Close/.test(e.message)) throw e; } } }
const data = await withRetry(() => collectStream(streamSse(response)));
Defensive patterns

Strategy: retry

Validate before calling

if (!response.ok || !response.body) { /* avoid entering streamResponse */ }

Try / catch

const run = async () => { for await (const c of streamSse(response)) out.push(c); }; for (let i = 0; i < 3; i++) { out = []; try { await run(); break; } catch (e) { if (!/Premature Close|Try again/.test(e.message) || i === 2) throw e; } }

Prevention

When it happens

Trigger: Server or proxy closes the connection before sending data: malformed early chunks, idle timeouts, keep-alive + low maxSockets on the http agent, or abrupt server shutdown.

Common situations: LLM endpoints dropping long-pending streaming requests, corporate proxies/LBs with short timeouts, keep-alive agent misconfiguration under concurrency.

Related errors


AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27). Data as JSON: /api/errors/40b757855cd6b74b. Report an issue: GitHub.