zeroclaw-labs/zeroclaw · error
Telegram sendDocument failed: {err}
Error message
Telegram sendDocument failed: {err} What it means
send_document() reads the file from disk and uploads it as a multipart sendDocument request (with optional caption and message_thread_id); any non-2xx answer bails with Telegram's response body embedded. The body's `description` is the authoritative reason.
Source
Thrown at crates/zeroclaw-channels/src/telegram.rs:3178
if let Some(tid) = thread_id {
form = form.text("message_thread_id", tid.to_string());
}
if let Some(cap) = caption {
form = form.text("caption", cap.to_string());
}
let resp = self
.http_client()
.post(self.api_url("sendDocument"))
.multipart(form)
.send()
.await?;
if !resp.status().is_success() {
let err = resp.text().await?;
anyhow::bail!("Telegram sendDocument failed: {err}");
}
::zeroclaw_log::record!(
INFO,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)
.with_attrs(::serde_json::json!({"chat_id": chat_id, "file_name": file_name})),
"document sent to"
);
Ok(())
}
/// Send a document from bytes (in-memory) to a Telegram chat
pub async fn send_document_bytes(
&self,
chat_id: &str,
thread_id: Option<&str>,
file_bytes: Vec<u8>,
file_name: &str,View on GitHub (pinned to 88bb9c8533)
Solutions
- Read the embedded body — `description` names the exact cause.
- Check the file size against the 50MB document cap and split or compress oversized files.
- Verify chat_id and, when used, that thread_id refers to an actual forum topic in that chat.
- On 429, honor retry_after and resend once.
Defensive patterns
Strategy: try-catch
Validate before calling
const DOC_LIMIT: u64 = 50 * 1024 * 1024;
let meta = tokio::fs::metadata(file_path).await?;
anyhow::ensure!(meta.len() <= DOC_LIMIT, "document {}MB exceeds 50MB", meta.len() / 1024 / 1024);
anyhow::ensure!(file_path.is_file(), "attachment is not a regular file"); Type guard
fn is_too_large(err: &anyhow::Error) -> bool {
err.to_string().contains("413") || err.to_string().contains("file is too big")
} Try / catch
if let Err(e) = channel.send_document(chat, thread, path, caption).await {
if is_too_large(&e) {
return channel.send_text_chunks("file too large to send", chat, thread).await;
}
return Err(e);
} Prevention
- Check file size against 50MB before reading it into memory.
- Verify chat_id and thread_id (forum topics only) before posting.
- Honor retry_after on 429; stop sending to 403 chats.
When it happens
Trigger: 413 when the file exceeds Telegram's 50MB document limit; 400 'chat not found' for a bad chat_id or a thread_id that is not a forum topic; 403 blocked/kicked; 429 flood control; invalid multipart payload when the file disappears between the exists-check and tokio::fs::read.
Common situations: Exporting large logs/archives over 50MB; sending to a chat the bot was removed from; wrong thread_id for non-forum chats; rapid-fire document sends tripping limits.
Related errors
- Telegram sendPhoto failed: {err}
- Telegram sendVideo failed: {err}
- Telegram sendAudio failed: {err}
- Telegram sendVoice failed: {err}
- {method} failed: status={status}, body={body}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/b4e72df172089895.
Report an issue: GitHub.