sipeed/picoclaw · error
slack auth test failed: %w
Error message
slack auth test failed: %w
What it means
SlackChannel.Start calls api.AuthTest() to validate the bot token and capture the bot's user/team IDs before opening the Socket Mode event loop. Any failure — invalid/revoked token, missing scope, network error, Slack outage — is wrapped as "slack auth test failed" with the original error intact. This is the first real network call the channel makes, so it is where bad credentials surface.
Source
Thrown at pkg/channels/slack/slack.go:90
postTextFn: func(ctx context.Context, channelID, threadTS, text string) error {
opts := []slack.MsgOption{slack.MsgOptionText(text, false)}
if threadTS != "" {
opts = append(opts, slack.MsgOptionTS(threadTS))
}
_, _, err := api.PostMessageContext(ctx, channelID, opts...)
return err
},
}, nil
}
func (c *SlackChannel) Start(ctx context.Context) error {
logger.InfoC("slack", "Starting Slack channel (Socket Mode)")
c.ctx, c.cancel = context.WithCancel(ctx)
authResp, err := c.api.AuthTest()
if err != nil {
return fmt.Errorf("slack auth test failed: %w", err)
}
c.botUserID = authResp.UserID
c.teamID = authResp.TeamID
logger.InfoCF("slack", "Slack bot connected", map[string]any{
"bot_user_id": c.botUserID,
"team": authResp.Team,
})
go c.eventLoop()
go func() {
if err := c.socketClient.RunContext(c.ctx); err != nil {
if c.ctx.Err() == nil {
logger.ErrorCF("slack", "Socket Mode connection error", map[string]any{
"error": err.Error(),
})
}View on GitHub (pinned to 49183d7e8d)
Solutions
- Unwrap the error: slack's client returns invalid_auth / token_expired reasons that name the exact problem; re-issue the affected token and update config.
- Verify the pairing: bot_token is xoxb- from the same Slack app as the xapp- app token.
- Test connectivity to slack.com (curl https://slack.com/api/auth.test) from the same host/container.
- If Slack reports a transient 5xx or network timeout, retry Start with backoff.
Example fix
// before
if err := slk.Start(ctx); err != nil { log.Fatal(err) }
// after: distinguish auth failure from transient error
if err := slk.Start(ctx); err != nil {
if strings.Contains(err.Error(), "invalid_auth") ||
strings.Contains(err.Error(), "token_expired") {
log.Fatal("slack: rotate the bot token in config") // permanent
}
log.Printf("slack: transient start failure, retrying: %v", err)
time.Sleep(5 * time.Second)
return slk.Start(ctx)
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight the same call Start uses
resp, err := slackClient.AuthTest()
if err != nil { return fmt.Errorf("slack token invalid before start: %w", err) }
_ = resp Try / catch
if err := ch.Start(ctx); err != nil {
msg := err.Error()
switch {
case strings.Contains(msg, "invalid_auth"), strings.Contains(msg, "token_expired"):
rotateTokenAndRestart() // permanent
case strings.Contains(msg, "slack auth test failed"): // wrapped network/5xx
retryWithBackoff(func() error { return ch.Start(ctx) })
}
} Prevention
- Prefix-check tokens before start (xoxb- for bot, xapp- for app)
- After reinstalling the Slack app, update the bot token in config — old ones are revoked
- Pre-flight AuthTest in a readiness probe so bad tokens fail the deploy, not the first message
When it happens
Trigger: Start() with an expired/revoked bot token (token_rotation/deactivated app); bot token lacking the auth.test permission; no egress to slack.com; Slack 5xx incident; tokens swapped between apps (xoxb of app A with xapp of app B).
Common situations: Reinstalling the Slack app which rotates the bot token while config keeps the old one; workspace admins revoking the app; corporate proxies blocking slack.com; using an app-level token in the bot_token field by mistake.
Related errors
- failed to start token refresh: %w
- reading usage response: %w
- failed to start stream client: %w
- failed to create discord session: %w
- failed to open discord session: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/be5096b3d9683ae0.
Report an issue: GitHub.