zeroclaw-labs/zeroclaw · error · anyhow::Error
attachment Content-Length ({len} bytes) exceeds {} MB limit
Error message
attachment Content-Length ({len} bytes) exceeds {} MB limit What it means
Before streaming the body, `download_remote_attachment` compares the response's `Content-Length` header against `WECHAT_MEDIA_MAX_BYTES` (100 MiB) and refuses downloads that would exceed the limit. This is an early-abort so oversized remote files are rejected without wasting bandwidth; the WeChat upload path cannot accept media beyond this size anyway.
Source
Thrown at crates/zeroclaw-channels/src/wechat.rs:1192
}
let resp = self
.client
.get(url)
.timeout(API_TIMEOUT)
.send()
.await
.with_context(|| format!("attachment download failed: {url}"))?;
if !resp.status().is_success() {
let status = resp.status();
let body = resp.text().await.unwrap_or_default();
anyhow::bail!("attachment download failed ({status}): {body}");
}
if let Some(len) = resp.content_length()
&& len > WECHAT_MEDIA_MAX_BYTES
{
anyhow::bail!(
"attachment Content-Length ({len} bytes) exceeds {} MB limit",
WECHAT_MEDIA_MAX_BYTES / (1024 * 1024)
);
}
let content_type = resp
.headers()
.get(reqwest::header::CONTENT_TYPE)
.and_then(|value| value.to_str().ok())
.map(str::to_string);
let bytes = resp.bytes().await?.to_vec();
if bytes.len() as u64 > WECHAT_MEDIA_MAX_BYTES {
anyhow::bail!(
"attachment exceeds {} MB limit",
WECHAT_MEDIA_MAX_BYTES / (1024 * 1024)
);
}View on GitHub (pinned to 88bb9c8533)
Solutions
- Compress, trim, or transcode the media below 100 MiB (e.g. lower video bitrate/resolution) and send the smaller URL.
- Host the oversized file elsewhere (file share, object storage with a share link) and send the link as message text rather than as an attachment.
- If the Content-Length looks wrong, verify with `curl -I <url>` what the server actually declares and fix the hosting.
- Do not raise `WECHAT_MEDIA_MAX_BYTES` casually — the WeChat iLink upload endpoint enforces its own ceiling and 100 MiB is the client-side contract.
Example fix
# before attachment.target = "https://cdn.example.com/meeting-recording.mkv" # 480 MB -> error 335 # after: compress under the 100 MiB ceiling, or share a link ffmpeg -i meeting-recording.mkv -b:v 800k meeting-recording-small.mp4 # < 100 MiB attachment.target = "https://cdn.example.com/meeting-recording-small.mp4" # or: send "Large file: https://cdn.example.com/meeting-recording.mkv" as plain text
Defensive patterns
Strategy: validation
Validate before calling
// check declared size before sending
async fn declared_size(client: &reqwest::Client, url: &str) -> Option<u64> {
let resp = client.head(url).send().await.ok()?;
resp.content_length()
}
if declared_size(&client, url).await.unwrap_or(0) > 100 * 1024 * 1024 {
anyhow::bail!("too large for WeChat attachment; share a link instead");
} Type guard
fn within_wechat_limit(len: u64) -> bool {
len <= 100 * 1024 * 1024 // WECHAT_MEDIA_MAX_BYTES
} Try / catch
match channel.send(msg_with_attachment(&url)).await {
Err(err) if err.to_string().contains("exceeds 100 MB limit") => {
// compress / re-host under the ceiling, or send a link in text
let share = rehost_under_limit(&url).await?;
channel.send(msg_with_text(&format!("File: {share}"))).await?;
}
other => other?,
} Prevention
- Enforce a 100 MiB ceiling in whatever produces attachment URLs (media pipeline, export jobs).
- HEAD-check Content-Length before send to fail fast without downloading.
- Remember the limit applies to local files too (error 338) — keep the ceiling in one shared constant/config.
When it happens
Trigger: Sending a WeChat attachment whose `https://` target responds 2xx with `Content-Length: > 104857600`. Typical for large video/audio files, disk images, or archives hosted behind a correct server. Fires only when the server declares the size; chunked/missing headers hit the post-read check instead (error 336).
Common situations: Bots forwarding large video files or recordings; attachment URLs pointing at raw recordings/exports (e.g. meeting recordings, datasets) exceeding 100 MiB; server config changes making previously-small files huge (wrong file served); test fixtures using oversized blobs.
Related errors
- attachment exceeds {} MB limit
- refusing non-HTTPS attachment URL: {url}
- attachment download failed ({status}): {body}
- inbound attachment exceeds {} MB limit
- matrix: marker URL {url} exceeded {MAX_MARKER_BYTES}-byte ca
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/839b3bf6e9c7da3e.
Report an issue: GitHub.