windmill-labs/windmill · warning

e (Slack chat.update response body read error propagated via

Error message

e (Slack chat.update response body read error propagated via anyhow)

What it means

When Windmill updates the original Slack approval message after a form submission, it reads the Slack HTTP response body to log it. If reading that body fails (connection dropped, TLS error, timeout mid-read), the anyhow-wrapped io error is propagated with `?` and surfaces as 'e (Slack chat.update response body read error propagated via anyhow)'. The Slack update itself may have succeeded; only reading the response text failed.

Source

Thrown at backend/windmill-api/src/slack_approvals.rs:1239

    let response = client
        .post("https://slack.com/api/chat.update")
        .bearer_auth(token) // Use the token for authentication
        .header("Content-Type", "application/json")
        .json(&payload)
        .send()
        .await
        .map_err(|e| Error::from(anyhow::Error::new(e)))?;

    if response.status().is_success() {
        tracing::debug!("Slack message updated successfully!");
    } else {
        tracing::error!(
            "Failed to update Slack message. Status: {}, Response: {:?}",
            response.status(),
            response
                .text()
                .await
                .map_err(|e| Error::from(anyhow::Error::new(e)))?
        );
    }

    Ok(())
}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Retry the submission update or the Slack chat.update call; body-read failures are usually transient network issues.
  2. Verify outbound HTTPS connectivity and proxy configuration from the worker to slack.com (no idle-connection killing middleboxes).
  3. Check worker logs for the preceding status code — if Slack returned an error (e.g. 404 channel_not_found), fix the underlying Slack issue (channel ID, token scopes) so the success path is taken.
  4. If persistent, pin/update reqwest/TLS versions and ensure the container has CA certificates installed.

Example fix

// before
let body = response.text().await.map_err(|e| Error::from(anyhow::Error::new(e)))?;
// after
let body = response.text().await.unwrap_or_else(|e| {
    tracing::warn!("failed to read Slack response body: {e}");
    String::new()
});
Defensive patterns

Strategy: try-catch

Try / catch

// transient network issue — surface but don't fail the whole approval flow
match response.text().await {
    Ok(body) => tracing::error!("Slack update failed. Status: {}, Body: {body}", response.status()),
    Err(e) => tracing::error!("Slack update failed. Status: {}, body unreadable: {e}", response.status()),
}

Prevention

When it happens

Trigger: Slack's chat.update API returned a response, but `response.text().await` fails while draining the body — network interruption, Slack closing the connection early, or proxy/TLS termination mid-response — inside update_original_slack_message when the update returned a non-success status and the code logs the body.

Common situations: Flaky corporate networks or egress proxies between Windmill and slack.com; Slack API 5xx responses with truncated bodies; container/network timeouts; transient DNS or connection resets in self-hosted clusters with unstable outbound connectivity.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/c62b57c5050854c7. Report an issue: GitHub.