plandex-ai/plandex · error

error receiving stream chunk: %w

Error message

error receiving stream chunk: %w

What it means

stream.Recv() returned a non-EOF error while reading a chunk from the model stream. The library wraps it and returns it alongside the partial accumulator result. Unlike EOF (632), this is a transport/protocol-level receive failure mid-stream.

Source

Thrown at app/server/model/client_stream.go:147

			if streamFinished {
				log.Println("Stream finished—timed out waiting for usage chunk")
				return accumulator.Result(false, nil), nil
			} else {
				log.Println("Stream timed out due to inactivity")
				return accumulator.Result(true, fmt.Errorf("stream timed out due to inactivity. The model is not responding.")), nil
			}
		default:
			response, err := stream.Recv()
			if err == io.EOF {
				if streamFinished {
					return accumulator.Result(false, nil), nil
				}

				err = fmt.Errorf("model stream ended unexpectedly: %w", err)
				return accumulator.Result(true, err), err
			}
			if err != nil {
				err = fmt.Errorf("error receiving stream chunk: %w", err)
				return accumulator.Result(true, err), err
			}

			if response.ID != "" {
				accumulator.SetGenerationId(response.ID)
			}

			if !receivedFirstChunk {
				receivedFirstChunk = true
				accumulator.SetFirstTokenAt(time.Now())
			}

			if !timer.Stop() {
				<-timer.C
			}
			timer.Reset(ACTIVE_STREAM_CHUNK_TIMEOUT)

			// Process the response

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the wrapped cause for status codes (429 → backoff retry, 5xx → retry later)
  2. Retry with exponential backoff for transient network errors
  3. Ensure no caller cancels streamCtx prematurely during long generations
  4. Verify TLS/network path stability (timeouts, proxies, VPNs)
  5. Check provider rate limits and quotas if 429s recur

Example fix

// before: fail immediately
return
// after: classify and retry on rate limit
if strings.Contains(err.Error(), "error receiving stream chunk") && strings.Contains(err.Error(), "429") {
    time.Sleep(backoff); retry()
}
Defensive patterns

Strategy: retry

Type guard

func isRecvChunkError(err error) bool { return err != nil && strings.Contains(err.Error(), "error receiving stream chunk") }

Try / catch

result, err := call()
if isRecvChunkError(err) {
    if strings.Contains(err.Error(), "429") { sleepWithBackoff(); return call() }
    return nil, err
}

Prevention

When it happens

Trigger: Any Recv() error that is not io.EOF: network reset, TLS error, HTTP error status surfaced by the client, malformed SSE chunk, context cancellation mid-Recv.

Common situations: Transient network blips between client and provider; provider returning 429/5xx mid-stream; request context cancelled by an upstream caller; TLS certificate issues; proxy (LiteLLM) crashing during streaming.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/e62d6b97a111181d. Report an issue: GitHub.