Tencent/WeKnora · error

parse qqbot credentials: %w

Error message

parse qqbot credentials: %w

What it means

The QQ bot adapter factory parses channel.Credentials into required fields (appId, clientSecret, etc.) and wraps any parse failure with this error. It fires when credentials are missing, malformed JSON, or lacking required keys.

Source

Thrown at internal/im/qqbot/factory.go:15

package qqbot

import (
	"context"
	"fmt"

	"github.com/Tencent/WeKnora/internal/im"
	"github.com/Tencent/WeKnora/internal/logger"
)

func NewFactory() im.AdapterFactory {
	return func(factoryCtx context.Context, channel *im.IMChannel, msgHandler func(context.Context, *im.IncomingMessage) error) (im.Adapter, context.CancelFunc, error) {
		creds, err := im.ParseCredentials(channel.Credentials)
		if err != nil {
			return nil, nil, fmt.Errorf("parse qqbot credentials: %w", err)
		}

		mode := im.ResolveMode(channel, "websocket")
		if mode != "websocket" {
			return nil, nil, fmt.Errorf("unsupported qqbot mode: %s (only websocket is supported)", mode)
		}

		client, err := NewClient(
			im.GetString(creds, "app_id"),
			im.GetString(creds, "client_secret"),
			im.GetString(creds, "api_base_url"),
			im.GetString(creds, "gateway_url"),
		)
		if err != nil {
			return nil, nil, err
		}

		longConn := NewLongConnClient(client, msgHandler)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set channel.Credentials to JSON containing the required keys (appId, clientSecret)
  2. Validate the credentials JSON with im.ParseCredentials in a startup check
  3. Re-create or update the IM channel record with correctly serialized JSON

Example fix

// before
channel.Credentials = "appId=123 secret=abc"
// after
channel.Credentials = `{"appId":"123","clientSecret":"abc"}`
Defensive patterns

Strategy: validation

Validate before calling

func validateQQBotCreds(raw string) error {
    var m map[string]string
    if err := json.Unmarshal([]byte(raw), &m); err != nil {
        return fmt.Errorf("credentials must be JSON: %w", err)
    }
    for _, k := range []string{"appId", "clientSecret"} {
        if m[k] == "" { return fmt.Errorf("missing credential key: %s", k) }
    }
    return nil
}

Try / catch

adapter, cancel, err := factory(ctx, channel, handler)
if err != nil && strings.Contains(err.Error(), "parse qqbot credentials") {
    return fmt.Errorf("channel credentials malformed: %w", err)
}

Prevention

When it happens

Trigger: An IM channel of type qqbot is created whose Credentials string is not valid JSON or is missing required keys, and a websocket adapter is being constructed via NewFactory.

Common situations: Credentials pasted as YAML/INI instead of JSON; typo'd key names; credentials lost during environment provisioning; channel created before secrets were injected.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/35397329d45cce3f. Report an issue: GitHub.