zeroclaw-labs/zeroclaw · warning · anyhow::Error
Discord add reaction failed ({status}): {err}
Error message
Discord add reaction failed ({status}): {err} What it means
add_reaction PUTs /channels/{channel_id}/messages/{message_id}/reactions/{emoji}/@me (URL-encoded by discord_reaction_url, skin-tone variants reduced to the base glyph). Non-2xx becomes this error with the response body. Interaction sentinel targets are filtered before the call since they are not real channels. Dominant causes: 403 50001 Missing Permissions (ADD_REACTIONS), 10014 Unknown Emoji (custom emoji from another guild or name typo), 429 rate limiting, 404 deleted message/channel.
Source
Thrown at crates/zeroclaw-channels/src/discord/mod.rs:3801
return Ok(());
}
let url = discord_reaction_url(channel_id, message_id, emoji);
let resp = self
.http_client()
.put(&url)
.header("Authorization", format!("Bot {}", self.bot_token))
.header("Content-Length", "0")
.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 add reaction failed ({status}): {err}");
}
Ok(())
}
async fn remove_reaction(
&self,
channel_id: &str,
message_id: &str,
emoji: &str,
) -> anyhow::Result<()> {
// Interaction sentinels are not channel ids (see add_reaction).
if parse_discord_interaction_target(channel_id).is_some() {
return Ok(());
}
let url = discord_reaction_url(channel_id, message_id, emoji);
let resp = selfView on GitHub (pinned to 88bb9c8533)
Solutions
- Match the body: 50001 → grant Add Reactions; 10014 → use a guild-available or standard unicode emoji; 429 → back off; 10008 → message gone, skip
- Prefer standard unicode glyphs for signal reactions instead of custom server emoji
- Grant the bot ADD_REACTIONS wherever it posts
- Treat reaction failure as best-effort: log it, never fail the send
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = channel.add_reaction(ch, msg_id, "⚠️").await {
tracing::warn!("signal reaction failed: {e}"); // decoration only; never fail the send
} Prevention
- Audit ADD_REACTIONS on every channel the bot posts to
- Use standard unicode emoji for cross-guild portability
- Never let reaction errors fail message delivery
When it happens
Trigger: Bot lacks Add Reactions on the target channel; using a :name:id: custom emoji not present in that guild; unicode emoji mangled by encoding (variation selectors stripped); reacting to a message deleted between send and react; reaction bursts hitting per-channel limits.
Common situations: Failure-signal reactions (⚠️ from decide_failure_reactions) applied in channels where the bot only has Send Messages; emoji copied from another server; restrictive role overrides.
Related errors
- non-success status {}
- Discord remove reaction failed ({status}): {err}
- channel does not support room invites
- AcpChannel does not support reactions
- ACP returned unknown permission optionId: {other}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/6123c681313920a8.
Report an issue: GitHub.