zeroclaw-labs/zeroclaw · error · anyhow::Error
Discord send message with files failed ({status}): {err}
Error message
Discord send message with files failed ({status}): {err} What it means
The multipart variant of the send wrapper posts a message envelope plus file attachments; a non-2xx Discord answer makes it bail with status and body inline. File sends fail differently from plain sends: size limits and attachment counts are the usual offenders.
Source
Thrown at crates/zeroclaw-channels/src/discord/rest.rs:144
format!("files[{idx}]"),
Part::bytes(bytes).file_name(filename),
);
}
let resp = client
.post(&url)
.header("Authorization", format!("Bot {bot_token}"))
.multipart(form)
.send()
.await?;
if !resp.status().is_success() {
let status = resp.status();
let err = resp
.text()
.await
.unwrap_or_else(|e| format!("<failed to read response body: {e}>"));
anyhow::bail!("Discord send message with files failed ({status}): {err}");
}
extract_message_id(resp).await
}
async fn extract_message_id(resp: reqwest::Response) -> anyhow::Result<String> {
let body: serde_json::Value = resp.json().await?;
body.get("id")
.and_then(|v| v.as_str())
.map(|s| s.to_string())
.ok_or_else(|| {
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)
.with_outcome(::zeroclaw_log::EventOutcome::Failure)
.with_attrs(::serde_json::json!({"field": "id"})),
"discord: send response missing id field"
);View on GitHub (pinned to 88bb9c8533)
Solutions
- Check the status/body: size-related 400/413 → compress, truncate, or link the artifact instead of attaching
- Cap attachments at 10 per message and split larger batches
- Grant the bot Attach Files on the target channel
- 401 → fix the bot token
Defensive patterns
Strategy: validation
Validate before calling
// Rust — pre-validate attachments against Discord's limits
const MAX_ATTACHMENTS: usize = 10;
fn attachments_precheck(files: &[FilePayload], cap_bytes: u64) -> Result<(), String> {
if files.len() > MAX_ATTACHMENTS {
return Err(format!("{} attachments exceeds Discord's limit of {MAX_ATTACHMENTS}", files.len()));
}
for f in files {
if f.bytes.is_empty() {
return Err(format!("attachment '{}' is empty", f.name));
}
if f.bytes.len() as u64 > cap_bytes {
return Err(format!("attachment '{}' exceeds the upload cap; compress or link it", f.name));
}
}
Ok(())
} Prevention
- Compress or chunk large artifacts before attaching
- Split replies that would carry more than 10 files into multiple messages
When it happens
Trigger: POST with multipart returns non-success: 413/400 for a file over the bot's upload cap, 400 for more than 10 attachments or a zero-byte file, 403 missing Attach Files permission, 401 bad token.
Common situations: Agent replies attaching generated artifacts (logs, screenshots, builds) larger than the current upload cap; too many files batched into one reply; Attach Files missing on a locked-down channel.
Related errors
- Discord gate-prompt finalize failed ({status})
- Discord send message failed ({status}): {err}
- delete message failed ({status}): {err}
- listing commands failed ({})
- QQ attachment too large ({} bytes, max {}): {target}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/20d72f1b914268f2.
Report an issue: GitHub.