bytebase/bytebase · warning
failed to send message to user %v
Error message
failed to send message to user %v
What it means
This is a wrapping error produced in the Slack webhook plugin's Post() when the goroutine that sends a per-user direct message fails for a given user u. The errlist package collects each per-user failure via multierr.AppendInto, so one bad recipient does not stop the others; the combined error is then logged with slog.Warn and the function returns false (indicating the notification was not delivered to all users). It means at least one Slack DM (chat.postMessage) failed for that specific user's email.
Source
Thrown at backend/plugin/webhook/slack/slack.go:286
err := func() error {
userID, err := p.lookupByEmail(ctx, u.Email)
if err != nil {
return errors.Wrapf(err, "failed to lookup user")
}
if userID == "" {
return errors.Errorf("failed to find user id for %v", u.Email)
}
channelID, err := p.openConversation(ctx, userID)
if err != nil {
return errors.Wrapf(err, "failed to open conversation")
}
if err := p.chatPostMessage(ctx, channelID, webhookCtx); err != nil {
return errors.Wrapf(err, "failed to post message")
}
sent[u.Email] = true
return nil
}()
multierr.AppendInto(&errs, errors.Wrapf(err, "failed to send message to user %v", u.Email))
}
return errs
}); err != nil {
slog.Warn("failed to send direct message to slack user", log.BBError(err), slog.String("event", webhookCtx.EventType))
return false
}
return true
}
View on GitHub (pinned to 1870550677)
Solutions
- Check the server logs for the accompanying 'failed to post message' cause and the Slack error code in the wrapped error
- Verify the Slack bot token is valid and the bot is a member of the target channel/user's DM scope
- Confirm the user's Slack identity mapping (email) still exists in the workspace
- Retry; if rate-limited (429), respect Slack's Retry-After or reduce notification fan-out
Example fix
// before
if err := p.chatPostMessage(ctx, channelID, webhookCtx); err != nil {
return errors.Wrapf(err, "failed to post message")
}
// after
if err := p.chatPostMessage(ctx, channelID, webhookCtx); err != nil {
var slackErr *slack.SlackErrorResponse
if errors.As(err, &slackErr) && slackErr.Err == "ratelimited" {
time.Sleep(retryAfter) // honor Retry-After before failing
return errors.Wrapf(err, "failed to post message")
}
return errors.Wrapf(err, "failed to post message")
} Defensive patterns
Strategy: try-catch
Validate before calling
// Verify Slack API reachability and token before sending // resp, err := slackClient.AuthTest(); err == nil && resp.OK
Type guard
func hasSlackUser(u *User) bool { return u != nil && u.Email != "" } Try / catch
// Go: multierr already isolates per-user failures; inspect the joined error
if err := p.Post(ctx, webhookCtx); err != nil {
slog.Warn("slack dm failed", log.BBError(err)) // parse per-user segments from err
} Prevention
- Keep the Slack bot installed and token valid; re-auth after app reinstall
- Invite the bot to the channel and confirm it may DM workspace members
- Monitor 429 rate limits when fanning out to many users
- Keep user email ↔ Slack identity mappings current
When it happens
Trigger: Post() iterates over Slack users resolved from the instance URL and calls chatPostMessage(ctx, channelID, webhookCtx) for each; any failure of that API call (invalid channel ID, Slack API error, expired bot token, network failure) is wrapped as 'failed to post message' then re-wrapped as 'failed to send message to user %v' with the user's email.
Common situations: Bot removed from the workspace or channel; user has DMs disabled or the bot is restricted from messaging them; invalid/stale Slack bot token after reinstallation; Slack API rate limiting (429) or transient network outage during bulk sends.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- dingtalk dm: got 0 user id, errs: %v
- failed to send message
- failed to marshal webhook POST request to %s
- failed to construct webhook POST request to %s
- failed to POST webhook to %s
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/073eeaa17b1779d8.
Report an issue: GitHub.