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.

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.

Appendix: 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)