zeroclaw-labs/zeroclaw · error

WeCom attachment download failed: kind={} msg_id={} url_targ

Error message

WeCom attachment download failed: kind={} msg_id={} url_target={} status={} body_preview={}

What it means

WeCom WS attachment downloads fetch the media URL and require a 2xx status; failures bail with a log-style message including the attachment kind, msg_id, a summarized URL target (via summarize_attachment_url_for_log), the HTTP status, and a 512-character body preview (truncate_for_log).

Source

Thrown at crates/zeroclaw-channels/src/wecom_ws.rs:1322

        let response = self
            .client
            .get(url)
            .send()
            .await
            .with_context(|| {
                format!(
                    "failed to download WeCom attachment: kind={} msg_id={} url_target={} elapsed_ms={}",
                    kind.as_str(),
                    inbound.msg_id,
                    url_target,
                    started.elapsed().as_millis(),
                )
            })?;
        let status = response.status();
        if !status.is_success() {
            let body = response.text().await.unwrap_or_default();
            let body_preview = truncate_for_log(&body, 512);
            anyhow::bail!(
                "WeCom attachment download failed: kind={} msg_id={} url_target={} status={} body_preview={}",
                kind.as_str(),
                inbound.msg_id,
                url_target,
                status,
                body_preview
            );
        }

        if let Some(len) = response.content_length()
            && len > self.cfg.max_file_size_bytes
        {
            wecom_log_warn!(
                "WeCom attachment skipped: declared size exceeds configured limit msg_id={} attachment_kind={} declared_bytes={} max_file_size_bytes={}",
                inbound.msg_id,
                kind.as_str(),
                len,
                self.cfg.max_file_size_bytes

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Read the embedded status and body preview: 403/expired → process attachments promptly or skip; 404 → media gone, request a resend; 5xx → retry with backoff
  2. Retry the download a bounded number of times for 5xx only
  3. Compare url_target in the message against the expected media host to spot proxy rewrites
Defensive patterns

Strategy: retry

Try / catch

Branch on the embedded status: 5xx → bounded retry with backoff; 403/404 (expired/gone media) → skip the attachment, log msg_id, and continue processing the message; anything else → log the body preview and dead-letter.

Prevention

When it happens

Trigger: An inbound WeCom message with media (image/file/voice) whose download URL returns 403 (expired URL or auth), 404 (media no longer retained), or 5xx (CDN/gateway error).

Common situations: Delayed processing after the signed media URL expired; wrong media proxy config; WeCom CDN issues; a proxy stripping auth headers or rewriting the URL (visible in url_target).

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/7ff693965d15c63b. Report an issue: GitHub.