sipeed/picoclaw · error
slack bot_token and app_token are required
Error message
slack bot_token and app_token are required
What it means
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.
Source
Thrown at pkg/channels/slack/slack.go:47
ctx context.Context
cancel context.CancelFunc
pendingAcks sync.Map
uploadFileFn func(context.Context, slack.UploadFileParameters) error
postTextFn func(context.Context, string, string, string) error
}
type slackMessageRef struct {
ChannelID string
Timestamp string
}
func NewSlackChannel(
bc *config.Channel,
cfg *config.SlackSettings,
messageBus *bus.MessageBus,
) (*SlackChannel, error) {
if cfg.BotToken.String() == "" || cfg.AppToken.String() == "" {
return nil, fmt.Errorf("slack bot_token and app_token are required")
}
api := slack.New(
cfg.BotToken.String(),
slack.OptionAppLevelToken(cfg.AppToken.String()),
)
socketClient := socketmode.New(api)
base := channels.NewBaseChannel("slack", cfg, messageBus, bc.AllowFrom,
channels.WithMaxMessageLength(40000),
channels.WithGroupTrigger(bc.GroupTrigger),
channels.WithReasoningChannelID(bc.ReasoningChannelID),
)
return &SlackChannel{
BaseChannel: base,
config: cfg,View on GitHub (pinned to 49183d7e8d)
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.
Example fix
# before
channels:
slack:
type: slack
settings:
bot_token: "xoxb-123-..."
# app_token missing
# after
channels:
slack:
type: slack
settings:
bot_token: "xoxb-123-..."
app_token: "xapp-1-A012345-..." # scope: connections:write Defensive patterns
Strategy: validation
Validate before calling
func slackTokensPresent(cfg *config.SlackSettings) error {
if cfg.BotToken.String() == "" || cfg.AppToken.String() == "" {
return fmt.Errorf("slack needs bot_token (xoxb-) and app_token (xapp-)")
}
if !strings.HasPrefix(cfg.BotToken.String(), "xoxb-") || !strings.HasPrefix(cfg.AppToken.String(), "xapp-") {
return fmt.Errorf("slack tokens look swapped: bot=xoxb-, app=xapp-")
}
return nil
} Try / catch
// Go: constructor returns this error synchronously; check it at channel creation and fail deployment config validation, not at runtime
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- feishu app_id or app_secret is empty
- QQ app_id and app_secret not configured
- wecom bot_id and secret are required
- must be in range 1-65535
- failed to load MCP servers: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/2aafb2c7d51dec0a.
Report an issue: GitHub.