sipeed/picoclaw · critical
wecom bot_id and secret are required
Error message
wecom bot_id and secret are required
What it means
WeComChannel construction fails fast when either BotID or Secret is empty in the WeCom settings. These are the minimum credentials the channel needs to authenticate with the WeCom gateway, so NewChannel refuses to build rather than starting a channel that would fail every command. This is a configuration error at startup, not a runtime send failure.
Source
Thrown at pkg/channels/wecom/wecom.go:113
return true
}
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.seen[id]; ok {
return false
}
if old := s.ring[s.idx]; old != "" {
delete(s.seen, old)
}
s.ring[s.idx] = id
s.idx = (s.idx + 1) % len(s.ring)
s.seen[id] = struct{}{}
return true
}
func NewChannel(bc *config.Channel, cfg *config.WeComSettings, messageBus *bus.MessageBus) (*WeComChannel, error) {
if cfg.BotID == "" || cfg.Secret.String() == "" {
return nil, fmt.Errorf("wecom bot_id and secret are required")
}
if cfg.WebSocketURL == "" {
cfg.WebSocketURL = wecomDefaultWebSocketURL
}
base := channels.NewBaseChannel(
"wecom",
cfg,
messageBus,
bc.AllowFrom,
channels.WithReasoningChannelID(bc.ReasoningChannelID),
)
ch := &WeComChannel{
BaseChannel: base,
config: cfg,
pending: make(map[string]chan wecomEnvelope),
turns: make(map[string][]wecomTurn),View on GitHub (pinned to 49183d7e8d)
Solutions
- Set both bot_id and secret in the channels.wecom settings block of the config file
- If values come from environment variables, verify they are actually exported and non-empty in the deployment environment (print the resolved config with the secret masked)
- Check for typos/renamed keys in the config against the WeComSettings struct definition
- Restart the service after fixing the config; the error occurs only at channel construction
Example fix
# before (config.yaml)
channels:
wecom:
bot_id: ""
# secret missing entirely
# after
channels:
wecom:
bot_id: "wecom-bot-123"
secret: "${WECOM_SECRET}" # exported and non-empty Defensive patterns
Strategy: validation
Validate before calling
func validateWeComConfig(cfg *config.WeComSettings) error {
if cfg.BotID == "" {
return errors.New("channels.wecom.bot_id is required")
}
if cfg.Secret.String() == "" {
return errors.New("channels.wecom.secret is required")
}
return nil
}
// run before constructing the channel / starting the app
if err := validateWeComConfig(cfg); err != nil {
return err
} Type guard
func isWeComMissingCredentials(err error) bool {
return err != nil && strings.Contains(err.Error(), "bot_id and secret are required")
} Try / catch
ch, err := wecom.NewChannel(bc, cfg, bus)
if err != nil {
if isWeComMissingCredentials(err) {
// fail startup loudly; do not run a degraded channel
log.Fatalf("config error: %v", err)
}
return err
} Prevention
- Fail fast at config load with a clear message instead of at channel construction
- Use env-var interpolation with a startup assertion that resolved values are non-empty
- Mask-check secrets in CI config validation (name-only, never print the value)
When it happens
Trigger: Instantiating the WeCom channel (via the channel manager during app bootstrap) with a config where channels.wecom.bot_id or channels.wecom.secret is missing or an empty string; Secret is a masked type, so it must have been set and .String() must return a non-empty value.
Common situations: Deploying with an incomplete YAML/JSON config (secret omitted in prod but present in dev); env-var interpolation producing an empty string (e.g. WECOM_SECRET not exported); renaming config keys in a template so the values never bind; copying an example config without filling in credentials.
Related errors
- feishu app_id or app_secret is empty
- QQ app_id and app_secret not configured
- slack bot_token and app_token are required
- must be in range 1-65535
- failed to load config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/e34ca61c7f5926a7.
Report an issue: GitHub.