zeroclaw-labs/zeroclaw · error · anyhow::Error
interaction followup edit failed ({status}): {err}
Error message
interaction followup edit failed ({status}): {err} What it means
discord_edit_interaction_response PATCHes the deferred interaction's @original message via {api_base}/webhooks/{app_id}/{token}/messages/@original, carrying the first ≤2000-char chunk plus embeds and action rows (called from deliver_interaction_answer in the send() path for interaction: recipients). Non-2xx becomes this error. Typical causes: interaction token expired (15-minute lifetime), the @original placeholder deleted by a user, or 50035 Invalid Form Body from embed/component violations (total embed length >6000, invalid component structure, empty content with no embeds).
Source
Thrown at crates/zeroclaw-channels/src/discord/interaction.rs:198
// interactive action rows (EPIC B). `to_rest_json` omits whichever are empty,
// so a plain text reply stays byte-identical.
let payload = DiscordOutgoing {
content: Some(content.to_string()),
embeds: embeds.to_vec(),
components: components.to_vec(),
..Default::default()
};
// without_url: transport errors embed the token-bearing URL.
let resp = client
.patch(&url)
.json(&payload.to_rest_json())
.send()
.await
.map_err(reqwest::Error::without_url)?;
if !resp.status().is_success() {
let status = resp.status();
let err = resp.text().await.unwrap_or_default();
anyhow::bail!("interaction followup edit failed ({status}): {err}");
}
Ok(())
}
/// Post an additional interaction followup message
/// (`POST {api_base}/webhooks/{app_id}/{token}`), used to deliver the answer
/// chunks beyond the first when a reply exceeds Discord's 2000-char limit.
pub(crate) async fn discord_post_interaction_followup(
client: &reqwest::Client,
app_id: &str,
interaction_token: &str,
api_base: &str,
content: &str,
) -> anyhow::Result<()> {
let url = format!("{api_base}/webhooks/{app_id}/{interaction_token}");
let resp = client
.post(&url)
.json(&DiscordOutgoing::text(content).to_rest_json())View on GitHub (pinned to 88bb9c8533)
Solutions
- Match the embedded status: 404/Unknown interaction → token expired; 10008 Unknown Message → placeholder deleted; 400 50035 → payload validation
- Finish interaction answers well inside 15 minutes — run long tools after delivering the answer
- On deleted @original, fall back to posting a fresh followup message (the webhook accepts new messages)
- Clamp embed sizes and validate component markers before delivery
Example fix
// before: only the @original edit
discord_edit_interaction_response(&client, app, tok, base, content, &embeds, &rows).await?;
// after: fall back to a followup post when @original is gone
if discord_edit_interaction_response(&client, app, tok, base, content, &embeds, &rows).await.is_err() {
discord_post_interaction_followup(&client, app, tok, base, content).await?;
} Defensive patterns
Strategy: fallback
Try / catch
if discord_edit_interaction_response(&client, app, tok, base, content, &embeds, &rows).await.is_err() {
// @original gone or token dead — a fresh followup still works while the token lives
discord_post_interaction_followup(&client, app, tok, base, content).await?;
} Prevention
- Deliver interaction answers well inside the 15-minute token TTL
- Clamp embed/component payloads before delivery to avoid 50035
- Log the Discord error body — 404 vs 10008 vs 50035 point to different remedies
When it happens
Trigger: Agent turn exceeding 15 minutes before the final edit; user deleting the "thinking…" placeholder first; [EMBED:...] payloads exceeding embed limits after prepare_outgoing_embeds; [COMPONENTS:...] markers producing invalid rows; empty content with no embeds/components.
Common situations: Slow agent pipelines (long tool runs) blowing the token TTL; users dismissing the deferred state; oversized embed descriptions or images; marker output from newer templates against stricter validation.
Related errors
- interaction followup post failed ({status}): {err}
- interaction defer failed ({status}): {err}
- modal open failed ({status}): {err}
- interaction autocomplete answer failed ({status}): {err}
- interaction reject failed ({status}): {err}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/2964785c23c860df.
Report an issue: GitHub.