zeroclaw-labs/zeroclaw · error · anyhow::Error
DM failed ( )
Error message
DM failed ({status}): {body} What it means
Raised by RedditChannel::send on the direct-message branch when POST {REDDIT_API_BASE}/api/compose returns a non-2xx status; the response body is included verbatim. Reddit reports DM failures through this endpoint with 429 rate limits ('you are doing that too much'), 400 validation errors (missing subject/recipient, NO_VERIFIED_EMAIL on the target), and 403 when the recipient has blocked the bot or the bot lacks PM permissions. It only fires for DM sends, not comment replies.
Solutions
- On 429/'too much': back off for several minutes — compose limits are stricter than comment limits
- Validate the recipient username and ensure the target account can receive PMs (verified email)
- On 401, refresh the access token; on repeated 403, test manually to see if the account is blocked or restricted
- Queue outbound DMs and drip-feed them instead of bursting
Defensive patterns
Strategy: retry
Try / catch
if let Err(err) = channel.send(&recipient, &dm).await {
let msg = format!("{err:#}");
if msg.starts_with("DM failed (429") || msg.contains("too much") {
enqueue_with_delay(dm, Duration::from_secs(600)); // drip-feed, don't fail
return Ok(());
}
return Err(err);
} Prevention
- Queue DMs and send them with spacing — compose limits are stricter than comment limits
- Verify recipient usernames and that targets can receive PMs (verified email)
- On persistent 403, stop sending to that user: likely blocked or restricted
When it happens
Trigger: send() runs the else-branch (Direct message) building /api/compose with to/subject/text; any non-success status triggers the bail at reddit.rs:327.
Common situations: Bots mass-DMing users and tripping Reddit's much stricter compose rate limits; target user has no verified email (Reddit rejects composing to them); bot account too young/low-karma for the compose API; recipient username typo'd or deleted; blocked by the recipient.
Related errors
- comment reply failed
- token refresh failed
- channel does not support room creation
- Discord send message failed
- Download failed ( )
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/a8f9d321093e6013.
Report an issue: GitHub.
Appendix: source
Thrown at crates/zeroclaw-channels/src/reddit.rs:327
let resp = client
.post(format!("{REDDIT_API_BASE}/api/compose"))
.bearer_auth(&token)
.header("User-Agent", USER_AGENT)
.form(&[
("to", message.recipient.as_str()),
("subject", subject),
("text", &message.content),
])
.send()
.await?;
let status = resp.status();
if !status.is_success() {
let body = resp
.text()
.await
.unwrap_or_else(|e| format!("<failed to read response: {e}>"));
bail!("DM failed ({status}): {body}");
}
}
Ok(())
}
async fn listen(&self, tx: tokio::sync::mpsc::Sender<ChannelMessage>) -> Result<()> {
// Initial auth
self.refresh_access_token().await?;
let scope = if self.subreddits.is_empty() {
String::new()
} else {
format!(
"in {}",
self.subreddits
.iter()
.map(|s| format!("r/{s}"))View on GitHub (pinned to 88bb9c8533)