chenhg5/cc-connect · critical
qqbot: app_secret is required
Error message
qqbot: app_secret is required
What it means
New() validates required credentials from the opts map before constructing the Platform. It type-asserts opts["app_id"] and opts["app_secret"] to string and returns this error when the app_secret key is absent, not a string, or an empty string. The QQ Bot API requires an app secret to exchange for access tokens, so construction without it is refused immediately.
Source
Thrown at platform/qqbot/qqbot.go:156
// msgTypeQuote indicates a quote (reply) message in the QQ Bot API.
const msgTypeQuote = 103
// msgElement represents a message element in QQ Bot event.
// For quote messages (message_type=103), msg_elements[0] contains the quoted content.
type msgElement struct {
Content string `json:"content"`
Attachments []attachment `json:"attachments"`
}
// New creates a new QQ Bot platform from config options.
func New(opts map[string]any) (core.Platform, error) {
appID, _ := opts["app_id"].(string)
if appID == "" {
return nil, fmt.Errorf("qqbot: app_id is required")
}
appSecret, _ := opts["app_secret"].(string)
if appSecret == "" {
return nil, fmt.Errorf("qqbot: app_secret is required")
}
sandbox, _ := opts["sandbox"].(bool)
allowFrom, _ := opts["allow_from"].(string)
shareSessionInChannel, _ := opts["share_session_in_channel"].(bool)
markdownSupport, _ := opts["markdown_support"].(bool)
intents := defaultIntents
if v, ok := opts["intents"].(int); ok && v > 0 {
intents = v
} else if v, ok := opts["intents"].(float64); ok && v > 0 {
intents = int(v)
}
core.CheckAllowFrom("qqbot", allowFrom)
dataDir, _ := opts["cc_data_dir"].(string)
return &Platform{
appID: appID,View on GitHub (pinned to 4000b2338a)
Solutions
- Set app_secret in the platform options as a plain string: opts["app_secret"] = "your-secret" in the config.toml [platforms.qqbot] section (or equivalent).
- Check the key spelling and casing — it must be exactly "app_secret".
- Ensure the value is a Go string, not []byte or another type; convert with string(b) if read from a file.
- Verify app_id is also set — New checks app_id first, so a missing app_id error can mask a missing secret until app_id is fixed.
Example fix
// before
opts := map[string]any{"app_id": "123"}
p, err := qqbot.New(opts) // qqbot: app_secret is required
// after
opts := map[string]any{"app_id": "123", "app_secret": os.Getenv("QQBOT_APP_SECRET")}
p, err := qqbot.New(opts) Defensive patterns
Strategy: validation
Validate before calling
func validateQQBotOpts(opts map[string]any) error {
id, _ := opts["app_id"].(string)
sec, _ := opts["app_secret"].(string)
if id == "" { return errors.New("qqbot opts: app_id missing or not a string") }
if sec == "" { return errors.New("qqbot opts: app_secret missing or not a string") }
return nil
} Type guard
sec, ok := opts["app_secret"].(string); if !ok || sec == "" { /* refuse to construct */ } Prevention
- Store secrets as plain strings, never []byte, when building the opts map.
- Validate the whole platform config at startup, before New(), with a fail-fast check.
- Use consistent key naming (snake_case) across all platform config blocks.
- Load secrets from env vars with a startup assertion that they are non-empty.
When it happens
Trigger: Calling qqbot.New(opts) where opts["app_secret"] is missing, is nil, or where its concrete type is not string (e.g. it was passed as []byte, a typed constant, or loaded from YAML/JSON as another type).
Common situations: Typo in the TOML/YAML key (appsecret, app-secret) so it never reaches opts; secret left out of an environment-driven config loader; secret declared as []byte from os.ReadFile; copying a Feishu/Telegram config block that has no app_secret field.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- config path not set
- app_id and app_secret are required
- token is required
- bot_token is required (format: app_key:app_secret)
- %s: app_id and app_secret are required
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/109af947ae24dcfd.
Report an issue: GitHub.