astrid-runtime/astrid · error
models response too large
Error message
models response too large (exceeded {MAX_RESPONSE_BYTES} bytes; aborted mid-stream) What it means
read_capped_body streams the response body while enforcing MAX_RESPONSE_BYTES; if the accumulated size would exceed the cap mid-stream it aborts and drops the rest. This handles chunked responses with no (or lying) Content-Length that passed the advertised-size check.
Solutions
- Ensure the endpoint returns a small models-list JSON body
- Put a proxy in front that caps/trims the response size
- Fix the server to advertise and send only the compact model list
Defensive patterns
Strategy: try-catch
Try / catch
match fetch_options(opts, values).await {
Err(e) if e.to_string().contains("too large") || e.to_string().contains("aborted mid-stream") => {
eprintln!("response exceeded size cap; enter model manually.");
prompt_free_text()?
}
other => other?,
} Prevention
- Prefer endpoints with accurate Content-Length and small JSON bodies
- Keep discovery responses well under MAX_RESPONSE_BYTES
- Never point capsule discovery at untrusted or unbounded endpoints
When it happens
Trigger: The endpoint sends more than MAX_RESPONSE_BYTES in a chunked/streamed response without an over-limit Content-Length — e.g. absent or false Content-Length header with a huge body.
Common situations: Malicious or misconfigured server streaming unlimited data; proxy stripping Content-Length while returning a large payload.
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
- capsule archive exceeds 50 MB limit
- models response too large
- exceeds size limit
- Distro.lock exceeds 1 MB limit
- Distro.sig exceeds size limit
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/132afced8f87d584.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/capsule/model_discovery.rs:283
/// **before** each chunk is appended, so the buffer never exceeds the cap
/// (the transfer is aborted the moment the next chunk would cross it). This
/// is the streaming guard the up-front `Content-Length` check cannot
/// provide: a chunked / unknown-length (or lying-`Content-Length`) response
/// is bounded by the bytes actually read, not by an advisory header.
///
/// Rejects an over-cap body and any non-UTF-8 payload; both errors map to
/// the free-text fallback at the call site.
async fn read_capped_body(response: reqwest::Response) -> anyhow::Result<String> {
use futures::StreamExt;
let mut stream = response.bytes_stream();
let mut body: Vec<u8> = Vec::new();
while let Some(chunk) = stream.next().await {
let chunk = chunk.context("error reading models response body")?;
// Check before appending so we never hold more than the cap plus the
// tail of one already-received chunk. The moment the total would
// exceed the limit we abort — the rest of the stream is dropped.
anyhow::ensure!(
body.len().saturating_add(chunk.len()) <= MAX_RESPONSE_BYTES,
"models response too large (exceeded {MAX_RESPONSE_BYTES} bytes; aborted mid-stream)"
);
body.extend_from_slice(&chunk);
}
String::from_utf8(body).context("models response was not valid UTF-8")
}
/// Bound an in-memory body and decode it as UTF-8 (test helper for the
/// streaming guard's cap/decoding logic).
///
/// Rejects a body larger than [`MAX_RESPONSE_BYTES`] and any non-UTF-8
/// payload — the same invariants [`read_capped_body`] enforces while
/// streaming.
#[cfg(test)]
fn decode_capped_body(body: &[u8]) -> anyhow::Result<String> {
anyhow::ensure!(
body.len() <= MAX_RESPONSE_BYTES,View on GitHub (pinned to affd8760f4)