chenhg5/cc-connect · error
empty access_token in response
Error message
empty access_token in response
What it means
The token response parsed as valid JSON but the access_token field was empty or missing. refreshToken rejects this explicitly (platform/qqbot/qqbot.go:593) because an empty token cannot authenticate subsequent API calls. This typically means QQ accepted the request but refused to issue a token, often returning an error payload with different field names.
Source
Thrown at platform/qqbot/qqbot.go:593
if err != nil {
return fmt.Errorf("token request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
raw, _ := io.ReadAll(resp.Body)
return fmt.Errorf("token request returned %d: %s", resp.StatusCode, raw)
}
var result struct {
AccessToken string `json:"access_token"`
ExpiresIn string `json:"expires_in"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return fmt.Errorf("token response decode: %w", err)
}
if result.AccessToken == "" {
return fmt.Errorf("empty access_token in response")
}
var expiresSec int
_, _ = fmt.Sscanf(result.ExpiresIn, "%d", &expiresSec)
if expiresSec <= 0 {
expiresSec = 7200
}
p.tokenMu.Lock()
p.token = result.AccessToken
p.tokenExpiry = time.Now().Add(time.Duration(expiresSec) * time.Second)
p.tokenMu.Unlock()
slog.Debug("qqbot: access token refreshed", "expires_in", expiresSec)
return nil
}
// getAccessToken returns the current token, refreshing if expired or near-expiry.View on GitHub (pinned to 4000b2338a)
Solutions
- Log the full response body to see the actual fields QQ returned (e.g. an error code/message object).
- Verify in the QQ open platform that the bot app has the required scopes and is approved for group/c2c messaging.
- Re-check appId/clientSecret — some QQ errors surface as 200 + error body rather than 4xx.
- If the key name changed, update cc-connect to a version matching the current QQ Bot API, or patch the result struct's json tag.
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight credential check via curl before deploying:
// curl -s -X POST <tokenURL> -d '{"appId":"...","clientSecret":"..."}' | jq -e '.access_token != ""' Try / catch
if err := platform.Start(ctx); err != nil {
if strings.Contains(err.Error(), "empty access_token") {
slog.Error("QQ refused token issuance (check app scopes/publish status); raw response logged at debug")
}
} Prevention
- Confirm the bot app is approved and has group/c2c message scopes in the QQ open platform console.
- Capture full token responses at debug level to see application-level error fields QQ returns inside 200 responses.
- Validate credentials with a one-off curl/jq check during deployment.
- Keep the SDK/cc-connect version in sync with the current QQ Bot API response format.
When it happens
Trigger: refreshToken decodes a 200 JSON body whose access_token field is "" — e.g. QQ returned an error object (code/message) with HTTP 200, or the appId is valid but the app lacks permission for this endpoint.
Common situations: App credentials valid but bot not yet published/scoped for the group/c2c APIs; QQ returning an application-level error inside a 200 response; response schema drift where the token lives under a different JSON key.
Understand the failure class
Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.
Related errors
- token request failed: %w
- token request returned %d: %s
- token response decode: %w
- get access token: %w
- qqbot: upload rich media: empty file_info
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/b0e84a69f3191b5d.
Report an issue: GitHub.