{"record":{"id":"289c8ebef6a6d017","repo":"sipeed/picoclaw","slug":"qq-app-id-and-app-secret-not-configured","errorCode":null,"errorMessage":"QQ app_id and app_secret not configured","messagePattern":"QQ app_id and app_secret not configured","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/qq/qq.go","lineNumber":104,"sourceCode":"func NewQQChannel(bc *config.Channel, cfg *config.QQSettings, messageBus *bus.MessageBus) (*QQChannel, error) {\n\tbase := channels.NewBaseChannel(\"qq\", cfg, messageBus, bc.AllowFrom,\n\t\tchannels.WithMaxMessageLength(cfg.MaxMessageLength),\n\t\tchannels.WithGroupTrigger(bc.GroupTrigger),\n\t\tchannels.WithReasoningChannelID(bc.ReasoningChannelID),\n\t)\n\n\treturn &QQChannel{\n\t\tBaseChannel: base,\n\t\tbc:          bc,\n\t\tconfig:      cfg,\n\t\tdedup:       make(map[string]time.Time),\n\t\tdone:        make(chan struct{}),\n\t}, nil\n}\n\nfunc (c *QQChannel) Start(ctx context.Context) error {\n\tif c.config.AppID == \"\" || c.config.AppSecret.String() == \"\" {\n\t\treturn fmt.Errorf(\"QQ app_id and app_secret not configured\")\n\t}\n\n\tbotgo.SetLogger(newBotGoLogger(\"botgo\"))\n\tlogger.InfoC(\"qq\", \"Starting QQ bot (WebSocket mode)\")\n\n\t// Reinitialize shutdown signal for clean restart.\n\tc.done = make(chan struct{})\n\tc.stopOnce = sync.Once{}\n\n\t// create token source\n\tcredentials := &token.QQBotCredentials{\n\t\tAppID:     c.config.AppID,\n\t\tAppSecret: c.config.AppSecret.String(),\n\t}\n\tc.tokenSource = token.NewQQBotTokenSource(credentials)\n\n\t// create child context\n\tc.ctx, c.cancel = context.WithCancel(ctx)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/qq/qq.go#L86-L122","documentation":"QQChannel.Start refuses to run when either config.AppID or config.AppSecret is empty. The QQ channel talks to the QQ open platform (botgo SDK), which requires an app_id/app_secret pair to mint access tokens; starting with blank credentials would only fail later with a confusing auth error, so the constructor fails fast at pkg/channels/qq/qq.go:104.","triggerScenarios":"Enabling the qq channel (channels.qq) without setting app_id / app_secret (json keys app_id, app_secret; env PICOCLAW_CHANNELS_QQ_APP_ID per pkg/config/config.go:574); leaving the secret as the empty SecureString default; typos in the env var name so the value never loads.","commonSituations":"Fresh installs that copied an example config with placeholder secrets; secrets provided via environment variables that are missing in systemd/Docker unit files; the secret set under the wrong YAML key or wrong channel stanza; rotating secrets and clearing the old one without writing the new one.","solutions":["Set channels.qq settings app_id and app_secret (or PICOCLAW_CHANNELS_QQ_APP_ID / corresponding secret env var) in the config file or environment.","Confirm the values landed: dump the loaded config (without printing the secret value) or check AppID != \"\" && AppSecret.String() != \"\" before Start.","Get the pair from the QQ open platform console (q.qq.com) for your bot application; app_id is numeric, app_secret is a long opaque string.","If using env vars, verify the exact PICOCLAW_CHANNELS_QQ_* names and that the process environment actually exports them."],"exampleFix":"# before\nchannels:\n  qq:\n    enabled: true\n    # credentials missing\n\n# after\nchannels:\n  qq:\n    enabled: true\n    settings:\n      app_id: \"102001234\"\n      app_secret: \"your-app-secret-from-qq-console\"","handlingStrategy":"validation","validationCode":"func qqReady(cfg *config.QQSettings) error {\n    if cfg.AppID == \"\" || cfg.AppSecret.String() == \"\" {\n        return fmt.Errorf(\"set channels.qq app_id/app_secret before start\")\n    }\n    return nil\n}\n// call before qqChannel.Start(ctx)","typeGuard":null,"tryCatchPattern":"// Go: if err := ch.Start(ctx); err != nil { if strings.Contains(err.Error(), \"not configured\") { return fmt.Errorf(\"deployment config incomplete: %w\", err) } ... }","preventionTips":["Fail fast in deploy scripts: assert QQ credentials present before enabling the channel","Store QQ secrets in the secret registry (devkey) instead of inline YAML","Use exact env var names (PICOCLAW_CHANNELS_QQ_APP_ID etc.) in unit files"],"tags":["qq","config","credentials","startup"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}