{"record":{"id":"be5096b3d9683ae0","repo":"sipeed/picoclaw","slug":"slack-auth-test-failed-w","errorCode":null,"errorMessage":"slack auth test failed: %w","messagePattern":"slack auth test failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/slack/slack.go","lineNumber":90,"sourceCode":"\t\tpostTextFn: func(ctx context.Context, channelID, threadTS, text string) error {\n\t\t\topts := []slack.MsgOption{slack.MsgOptionText(text, false)}\n\t\t\tif threadTS != \"\" {\n\t\t\t\topts = append(opts, slack.MsgOptionTS(threadTS))\n\t\t\t}\n\t\t\t_, _, err := api.PostMessageContext(ctx, channelID, opts...)\n\t\t\treturn err\n\t\t},\n\t}, nil\n}\n\nfunc (c *SlackChannel) Start(ctx context.Context) error {\n\tlogger.InfoC(\"slack\", \"Starting Slack channel (Socket Mode)\")\n\n\tc.ctx, c.cancel = context.WithCancel(ctx)\n\n\tauthResp, err := c.api.AuthTest()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"slack auth test failed: %w\", err)\n\t}\n\tc.botUserID = authResp.UserID\n\tc.teamID = authResp.TeamID\n\n\tlogger.InfoCF(\"slack\", \"Slack bot connected\", map[string]any{\n\t\t\"bot_user_id\": c.botUserID,\n\t\t\"team\":        authResp.Team,\n\t})\n\n\tgo c.eventLoop()\n\n\tgo func() {\n\t\tif err := c.socketClient.RunContext(c.ctx); err != nil {\n\t\t\tif c.ctx.Err() == nil {\n\t\t\t\tlogger.ErrorCF(\"slack\", \"Socket Mode connection error\", map[string]any{\n\t\t\t\t\t\"error\": err.Error(),\n\t\t\t\t})\n\t\t\t}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/slack/slack.go#L72-L108","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nif err := slk.Start(ctx); err != nil { log.Fatal(err) }\n\n// after: distinguish auth failure from transient error\nif err := slk.Start(ctx); err != nil {\n    if strings.Contains(err.Error(), \"invalid_auth\") ||\n       strings.Contains(err.Error(), \"token_expired\") {\n        log.Fatal(\"slack: rotate the bot token in config\") // permanent\n    }\n    log.Printf(\"slack: transient start failure, retrying: %v\", err)\n    time.Sleep(5 * time.Second)\n    return slk.Start(ctx)\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight the same call Start uses\nresp, err := slackClient.AuthTest()\nif err != nil { return fmt.Errorf(\"slack token invalid before start: %w\", err) }\n_ = resp","typeGuard":null,"tryCatchPattern":"if err := ch.Start(ctx); err != nil {\n    msg := err.Error()\n    switch {\n    case strings.Contains(msg, \"invalid_auth\"), strings.Contains(msg, \"token_expired\"):\n        rotateTokenAndRestart() // permanent\n    case strings.Contains(msg, \"slack auth test failed\"): // wrapped network/5xx\n        retryWithBackoff(func() error { return ch.Start(ctx) })\n    }\n}","preventionTips":["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"],"tags":["slack","auth","token","network","startup"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}