Hmbown/CodeWhale · error · StreamError::Overflow

stream_overflow

stream_overflow

Error message

Stream exceeded maximum content size of {limit_bytes} bytes, closing

What it means

A guard in the stream loop enforces a maximum number of accumulated content bytes. When the streamed response exceeds max_content_bytes, a StreamError::Overflow envelope is logged, emitted as an error event, and the stream loop breaks. This prevents unbounded memory growth from runaway generations.

Solutions

  1. Raise the max stream content bytes configuration if large outputs are legitimate.
  2. Reduce the requested output size (lower max_tokens) so the response fits the budget.
  3. Detect and avoid degenerate model repetition loops (adjust temperature/frequency penalties).
  4. Split the work across multiple turns instead of one giant streamed response.

Example fix

// before
max_content_bytes = 1 MiB  // large refactors overflow
// after
max_content_bytes = 16 MiB
Defensive patterns

Strategy: validation

Validate before calling

// ensure the requested output budget fits under the byte cap
let max_bytes = max_tokens * 4; // ~4 bytes/token
if max_bytes > max_content_bytes { lower_max_tokens(); }

Prevention

When it happens

Trigger: In run_turn's streaming loop, stream_content_bytes exceeds max_content_bytes after accumulating deltas; StreamError::Overflow { limit_bytes } is built via into_envelope() and the loop breaks.

Common situations: A model stuck in a repetition loop emitting megabytes of tokens; adversarial or pathological prompts producing enormous outputs; a misconfigured content-size limit that is too small for legitimate large code-generation tasks.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/160798a5e31fb1ed. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/core/engine/turn_loop.rs:4842

            // Guard: max wall-clock duration
            if stream_start.elapsed() > max_duration {
                let envelope = StreamError::DurationLimit {
                    limit_secs: max_duration_secs,
                }
                .into_envelope();
                crate::logging::warn(&envelope.message);
                stream_error.get_or_insert(envelope.message.clone());
                let _ = self.tx_event.send(Event::error(envelope)).await;
                break;
            }

            // Guard: max accumulated content bytes
            if stream_content_bytes > max_content_bytes {
                let envelope = StreamError::Overflow {
                    limit_bytes: max_content_bytes,
                }
                .into_envelope();
                crate::logging::warn(&envelope.message);
                stream_error.get_or_insert(envelope.message.clone());
                let _ = self.tx_event.send(Event::error(envelope)).await;
                break;
            }

            let event = match event_result {
                Ok(e) => {
                    last_progress_mono = Instant::now();
                    last_progress_wall = std::time::SystemTime::now();
                    // Only content-bearing events make a stream productive.
                    // Ping, usage/terminal deltas, block stops, and MessageStop
                    // are protocol bookkeeping; counting them as content hid
                    // empty/truncated provider responses from retry policy and
                    // produced false time-to-first-token measurements.
                    if !any_content_received && stream_event_has_actionable_content(&e) {
                        any_content_received = true;
                        first_token_at.get_or_insert_with(Instant::now);
                    }

View on GitHub (pinned to 73e0f67d83)