Tencent/WeKnora · error
empty qqbot access token: code=%d message=%s
Error message
empty qqbot access token: code=%d message=%s
What it means
After a successful token request, the QQ bot API responded with an empty access_token. The client treats this as a hard failure and includes the API's code and message fields, which usually indicate credential rejection.
Source
Thrown at internal/im/qqbot/client.go:195
func (c *Client) AccessToken(ctx context.Context) (string, error) {
c.mu.Lock()
if c.accessToken != "" && time.Until(c.expiresAt) > time.Minute {
token := c.accessToken
c.mu.Unlock()
return token, nil
}
c.mu.Unlock()
body := map[string]string{
"appId": c.appID,
"clientSecret": c.clientSecret,
}
var result tokenResponse
if err := c.doJSON(ctx, http.MethodPost, appTokenURL, body, &result); err != nil {
return "", err
}
if result.AccessToken == "" {
return "", fmt.Errorf("empty qqbot access token: code=%d message=%s", result.Code, result.Message)
}
expiresIn := parseExpiresIn(result.ExpiresIn)
c.mu.Lock()
c.accessToken = result.AccessToken
c.expiresAt = time.Now().Add(time.Duration(expiresIn) * time.Second)
c.mu.Unlock()
return result.AccessToken, nil
}
func parseExpiresIn(raw json.RawMessage) int {
if len(raw) == 0 {
return 7200
}
var number int
if err := json.Unmarshal(raw, &number); err == nil && number > 0 {
return number
}View on GitHub (pinned to 988cbb0330)
Solutions
- Verify AppID and AppSecret in the channel credentials against the QQ developer console
- Read the code/message fields in the error — they state the API's rejection reason
- Confirm the app is approved/enabled and the correct api_base_url is used
Example fix
// before
creds := map[string]string{"appId": "", "clientSecret": ""}
// after
creds := map[string]string{"appId": "1020xxxxx", "clientSecret": "correct-secret-from-console"} Defensive patterns
Strategy: validation
Validate before calling
if creds["appId"] == "" || creds["clientSecret"] == "" {
return errors.New("qqbot appId and clientSecret are required before requesting a token")
} Try / catch
token, err := client.AccessToken(ctx)
if err != nil {
if strings.Contains(err.Error(), "empty qqbot access token") {
return fmt.Errorf("check AppID/AppSecret in QQ console: %w", err)
}
return err
} Prevention
- Verify AppID/AppSecret in the QQ developer console
- Rotate secrets consistently on both sides
- Confirm the app is approved and enabled
- Use the correct api_base_url region
When it happens
Trigger: AccessToken POSTs appId/clientSecret to the app token endpoint and the response struct has AccessToken == "" — typically because credentials are wrong, the app is disabled, or the API returned an error payload with 2xx/4xx that still decoded.
Common situations: Misconfigured QQBOT_APPID / QQBOT_APPSECRET; app not yet approved or sandbox restrictions; wrong api_base_url routing to a mock returning empty tokens; app secret rotated server-side.
Related errors
- invalid APPID or APPSECRET (HTTP %d)
- parse qqbot credentials: %w
- OIDC provider returned no user claims
- id_token missing sub claim
- E2BAPIKey is required for the E2B backend
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/af2e2f0fa5509f81.
Report an issue: GitHub.