we-promise/sure · error · Assistant::Error

External assistant stream exceeded maximum buffer size.

Error message

External assistant stream exceeded maximum buffer size.

What it means

Raised by Assistant::External::Client#stream_response when the incremental SSE buffer exceeds MAX_SSE_BUFFER = 1 MB (app/models/assistant/external/client.rb:10). The buffer only drains when a newline-terminated line is sliced off, so it guards both against a single enormous SSE line and against upstreams that stream a giant payload with no newlines at all.

Source

Thrown at app/models/assistant/external/client.rb:83

  private

    def stream_response(http, request, &block)
      model = nil
      buffer = +""
      done = false

      http.request(request) do |response|
        unless response.is_a?(Net::HTTPSuccess)
          Rails.logger.warn("[External::Client] Upstream HTTP #{response.code}: #{response.body.to_s.truncate(500)}")
          raise Assistant::Error, "External assistant returned HTTP #{response.code}."
        end

        response.read_body do |chunk|
          break if done
          buffer << chunk

          if buffer.bytesize > MAX_SSE_BUFFER
            raise Assistant::Error, "External assistant stream exceeded maximum buffer size."
          end

          while (line_end = buffer.index("\n"))
            line = buffer.slice!(0..line_end).strip
            next if line.empty?
            next unless line.start_with?("data:")

            data = line.delete_prefix("data:")
            data = data.delete_prefix(" ") # SSE spec: strip one optional leading space

            if data == "[DONE]"
              done = true
              break
            end

            parsed = parse_sse_data(data)
            next unless parsed

View on GitHub (pinned to e69894adb9)

Solutions

  1. Confirm the upstream actually streams SSE: newline-terminated `data: {...}` lines ending with `data: [DONE]` — test with curl -N.
  2. If the endpoint only returns non-streamed JSON, point the client at a streaming-capable route rather than raising the cap.
  3. If legitimate single events exceed 1 MB (e.g. giant tool payloads in content), raise MAX_SSE_BUFFER in app/models/assistant/external/client.rb:10 — it is a class constant, not env-configurable.
  4. Check the logged upstream path for HTML error pages (proxy 502 pages) that arrive without newlines.

Example fix

# before (class constant, client.rb:10)
MAX_SSE_BUFFER = 1_048_576 # 1 MB

# after — raise the cap when legitimate events are larger
MAX_SSE_BUFFER = 4_194_304 # 4 MB
Defensive patterns

Strategy: try-catch

Try / catch

begin
  client.chat(messages: msgs) { |c| stream.write(c) }
rescue Assistant::Error => e
  raise unless e.message.include?("buffer size")
  # do not blind-retry: the upstream is sending non-SSE or oversized events
  Rails.logger.error("SSE buffer cap hit — verify upstream streams newline-delimited events")
  raise
end

Prevention

When it happens

Trigger: Upstream ignores the Accept: text/event-stream request header and returns one multi-megabyte JSON body without newline line breaks, so buffer << chunk accumulates past 1 MiB before the `while (line_end = buffer.index("\n"))` loop ever consumes anything; or a single data: line (one huge JSON event with a very long content delta) crosses the 1 MB cap; or a non-SSE error page/HTML stream without newlines.

Common situations: Gateway in front of the agent that buffers the whole response and sends it in one shot; upstream returning full-completion JSON instead of token-streamed SSE; prompt/model misconfiguration making the model emit a single gigantic output; misrouted URL serving an HTML page.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/92736caafcb619a7. Report an issue: GitHub.