zeroclaw-labs/zeroclaw · warning · anyhow::Error

assistant.threads.setStatus failed: {}

Error message

assistant.threads.setStatus failed: {}

What it means

Raised when the Slack assistant.threads.setStatus call returns ok != true; {err} is Slack's error string ('invalid_auth' if the token lacks the assistant scope, thread-related errors when the thread is unknown, etc.). setStatus only updates the visual 'thinking/typing' status badge on an assistant thread, so this failure is cosmetic: the actual message content is delivered by separate calls and is unaffected.

Source

Thrown at crates/zeroclaw-channels/src/slack.rs:1005

        status: &str,
    ) -> anyhow::Result<()> {
        let body = serde_json::json!({
            "channel_id": target.channel_id,
            "thread_ts": target.thread_ts,
            "status": status,
        });

        let response = self
            .http_client()
            .post(self.slack_api_url("assistant.threads.setStatus"))
            .bearer_auth(&self.bot_token)
            .json(&body)
            .send()
            .await?
            .error_for_status()?;
        let response: serde_json::Value = response.json().await?;
        if response.get("ok") != Some(&serde_json::Value::Bool(true)) {
            anyhow::bail!(
                "assistant.threads.setStatus failed: {}",
                response
                    .get("error")
                    .and_then(serde_json::Value::as_str)
                    .unwrap_or("unknown")
            );
        }
        Ok(())
    }

    fn http_client(&self) -> reqwest::Client {
        zeroclaw_config::schema::build_channel_proxy_client_with_timeouts(
            "channel.slack",
            self.proxy_url.as_deref(),
            30,
            10,
        )
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Treat as non-fatal: log and continue — the status badge is decorative and the reply still sends
  2. 'invalid_auth'-family codes: add the required assistant bot token scopes and reinstall the app
  3. Thread/channel errors: verify the bot is still in the channel and the ts refers to a live thread
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(err) = channel.set_thread_status(channel_id, thread_ts, status).await {
    ::zeroclaw_log::record!(WARN, ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note), format!("assistant status update failed (non-fatal): {err:#}"));
    // continue — status badge is cosmetic; the reply itself still sends
}
Ok(())

Prevention

When it happens

Trigger: A draft/status update path POSTs assistant.threads.setStatus with the thread's channel+ts and a status string; Slack answers ok=false — most often because the app token does not include the assistant thread scope, the thread ts is stale/invalid, or the bot lost access to the channel.

Common situations: Slack app manifest missing assistant scopes after adding the channel integration later; status update racing the user closing the thread; bot removed from the channel mid-conversation.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/7375219c2c43c2ee. Report an issue: GitHub.