chenhg5/cc-connect · critical

qqbot: failed to get access token: %w

Error message

qqbot: failed to get access token: %w

What it means

Start() calls refreshToken() to obtain the initial access token from the QQ Bot auth endpoint before connecting the gateway. If the token request fails (auth error, network failure, non-200 response), Start aborts and wraps the underlying error with this message. Without a valid token no further API calls can succeed, so startup is halted.

Source

Thrown at platform/qqbot/qqbot.go:196

		shareSessionInChannel: shareSessionInChannel,
		intents:               intents,
		markdownSupport:       markdownSupport,
		messageCachePath:      qqbotMessageCachePath(dataDir),
	}, nil
}

func (p *Platform) Name() string { return "qqbot" }

// Start connects to the QQ Bot gateway and begins receiving events.
func (p *Platform) Start(handler core.MessageHandler) error {
	p.handler = handler
	if err := p.loadMessageCache(); err != nil {
		slog.Warn("qqbot: load message cache failed", "error", err)
	}

	// Get initial access token
	if err := p.refreshToken(); err != nil {
		return fmt.Errorf("qqbot: failed to get access token: %w", err)
	}

	ctx, cancel := context.WithCancel(context.Background())
	p.ctx = ctx
	p.cancel = cancel

	if err := p.connectGateway(ctx); err != nil {
		cancel()
		return fmt.Errorf("qqbot: failed to connect gateway: %w", err)
	}

	slog.Info("qqbot: connected to QQ Bot gateway", "sandbox", p.sandbox)
	return nil
}

// Reply sends a message as a reply to an incoming message.
func (p *Platform) Reply(ctx context.Context, replyCtx any, content string) error {
	return p.Send(ctx, replyCtx, content)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify app_id/app_secret are correct and still valid on the QQ Bot open platform console.
  2. Match the sandbox option to the credential environment: sandbox=true only for test-bed credentials.
  3. Check outbound network access to the QQ Bot auth endpoint (proxy/firewall/DNS); set proxy env vars if needed.
  4. Retry Start() with backoff if the failure is transient (network 5xx/timeout).
  5. Inspect the wrapped inner error (%w) for the exact HTTP status / auth message returned by the API.

Example fix

// before
if err := platform.Start(ctx); err != nil { slog.Error("start failed", "error", err); os.Exit(1) }
// after
var err error
for i := 0; i < 3; i++ {
    if err = platform.Start(ctx); err == nil || !strings.Contains(err.Error(), "failed to get access token") {
        break
    }
    time.Sleep(time.Duration(1<<i) * time.Second)
}
if err != nil { slog.Error("start failed", "error", err); os.Exit(1) }
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: confirm auth endpoint reachability before Start
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, authURL, strings.NewReader(""))
resp, err := http.DefaultClient.Do(req)
if err != nil { return fmt.Errorf("auth endpoint unreachable: %w", err) }
resp.Body.Close()

Try / catch

if err := p.Start(ctx); err != nil {
    if strings.Contains(err.Error(), "failed to get access token") {
        // inspect errors.Unwrap(err) for HTTP status; retry with backoff
    }
}

Prevention

When it happens

Trigger: Calling Start() when the app_id/app_secret are wrong (auth endpoint rejects the exchange), the host cannot reach the QQ Bot auth API (offline, firewall, DNS), the sandbox flag does not match the credentials, or refreshToken's HTTP request returns an error/non-2xx.

Common situations: Rotated or revoked app secret in a production config; running with sandbox=true but production credentials (or vice versa); corporate proxy blocking api.sgroup.qq.com; QQ开放平台 app not yet approved/published; transient network blip at daemon boot.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/f1173d763c396910. Report an issue: GitHub.