{"record":{"id":"2aafb2c7d51dec0a","repo":"sipeed/picoclaw","slug":"slack-bot-token-and-app-token-are-required","errorCode":null,"errorMessage":"slack bot_token and app_token are required","messagePattern":"slack bot_token and app_token are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/slack/slack.go","lineNumber":47,"sourceCode":"\tctx          context.Context\n\tcancel       context.CancelFunc\n\tpendingAcks  sync.Map\n\tuploadFileFn func(context.Context, slack.UploadFileParameters) error\n\tpostTextFn   func(context.Context, string, string, string) error\n}\n\ntype slackMessageRef struct {\n\tChannelID string\n\tTimestamp string\n}\n\nfunc NewSlackChannel(\n\tbc *config.Channel,\n\tcfg *config.SlackSettings,\n\tmessageBus *bus.MessageBus,\n) (*SlackChannel, error) {\n\tif cfg.BotToken.String() == \"\" || cfg.AppToken.String() == \"\" {\n\t\treturn nil, fmt.Errorf(\"slack bot_token and app_token are required\")\n\t}\n\n\tapi := slack.New(\n\t\tcfg.BotToken.String(),\n\t\tslack.OptionAppLevelToken(cfg.AppToken.String()),\n\t)\n\n\tsocketClient := socketmode.New(api)\n\n\tbase := channels.NewBaseChannel(\"slack\", cfg, messageBus, bc.AllowFrom,\n\t\tchannels.WithMaxMessageLength(40000),\n\t\tchannels.WithGroupTrigger(bc.GroupTrigger),\n\t\tchannels.WithReasoningChannelID(bc.ReasoningChannelID),\n\t)\n\n\treturn &SlackChannel{\n\t\tBaseChannel:  base,\n\t\tconfig:       cfg,","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/slack/slack.go#L29-L65","documentation":"NewSlackChannel requires both a bot token (xoxb-..., used for Web API calls) and an app-level token (xapp-..., used for Socket Mode). Empty values are rejected before any Slack client is built. Socket Mode cannot work without the app token's connections:write scope, so this is a fail-fast guard rather than a recoverable runtime condition.","triggerScenarios":"Constructing a slack channel with slack settings where bot_token or app_token (json keys bot_token, app_token; env PICOCLAW_CHANNELS_SLACK_BOT_TOKEN per pkg/config/config.go:587) is empty or unset; providing only one of the two tokens; env var names misspelled so SecureString stays empty.","commonSituations":"Creating a Slack app and copying only the bot token; forgetting to generate an app-level token under Basic Information > App-Level Tokens with connections:write; deploying with only PICOCLAW_CHANNELS_SLACK_BOT_TOKEN set; tokens stored in a secret manager that returns empty on permission errors.","solutions":["Set both settings: bot_token (starts with xoxb-) and app_token (starts with xapp-) in channels.<name>.settings for the slack channel.","Create the app-level token in the Slack app config (App-Level Tokens, scope connections:write) if you do not have one.","Verify env vars if configuring via environment: exact PICOCLAW_CHANNELS_SLACK_* names, exported in the service unit/container.","Install the app to the workspace so the bot token is valid."],"exampleFix":"# before\nchannels:\n  slack:\n    type: slack\n    settings:\n      bot_token: \"xoxb-123-...\"\n      # app_token missing\n\n# after\nchannels:\n  slack:\n    type: slack\n    settings:\n      bot_token: \"xoxb-123-...\"\n      app_token: \"xapp-1-A012345-...\"  # scope: connections:write","handlingStrategy":"validation","validationCode":"func slackTokensPresent(cfg *config.SlackSettings) error {\n    if cfg.BotToken.String() == \"\" || cfg.AppToken.String() == \"\" {\n        return fmt.Errorf(\"slack needs bot_token (xoxb-) and app_token (xapp-)\")\n    }\n    if !strings.HasPrefix(cfg.BotToken.String(), \"xoxb-\") || !strings.HasPrefix(cfg.AppToken.String(), \"xapp-\") {\n        return fmt.Errorf(\"slack tokens look swapped: bot=xoxb-, app=xapp-\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Go: constructor returns this error synchronously; check it at channel creation and fail deployment config validation, not at runtime","preventionTips":["Generate the app-level token with connections:write scope when setting up the app","Prefix-check tokens (xoxb-/xapp-) to catch swaps before runtime","Use the PICOCLAW_CHANNELS_SLACK_* env vars consistently in unit files"],"tags":["slack","config","credentials","socket-mode","startup"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}