chenhg5/cc-connect · error

%s: fetch tenant access token code=%d msg=%s

Error message

%s: fetch tenant access token code=%d msg=%s

What it means

The tenant_access_token request completed but Feishu returned a business error (resp.Success()==false); the Feishu error code and message are included. This typically indicates the app credentials were rejected during token issuance.

Source

Thrown at platform/feishu/feishu.go:4112

	freshToken, refreshErr := p.fetchFreshTenantAccessToken(ctx)
	if refreshErr != nil {
		return fmt.Errorf("%s: %s failed after token refresh attempt: %w (original error: %v)", p.tag(), operation, refreshErr, err)
	}

	slog.Warn(p.tag()+": retrying request with fresh tenant access token", "operation", operation)
	return fn(p.replayAPIClient(), larkcore.WithTenantAccessToken(freshToken))
}

func (p *Platform) fetchFreshTenantAccessToken(ctx context.Context) (string, error) {
	resp, err := p.replayAPIClient().GetTenantAccessTokenBySelfBuiltApp(ctx, &larkcore.SelfBuiltTenantAccessTokenReq{
		AppID:     p.appID,
		AppSecret: p.appSecret,
	})
	if err != nil {
		return "", fmt.Errorf("%s: fetch tenant access token: %w", p.tag(), err)
	}
	if !resp.Success() {
		return "", fmt.Errorf("%s: fetch tenant access token code=%d msg=%s", p.tag(), resp.Code, resp.Msg)
	}
	if strings.TrimSpace(resp.TenantAccessToken) == "" {
		return "", fmt.Errorf("%s: fetch tenant access token returned empty token", p.tag())
	}
	return resp.TenantAccessToken, nil
}

func (p *Platform) replayAPIClient() *lark.Client {
	p.replayClientMu.Lock()
	defer p.replayClientMu.Unlock()
	if p.replayClient == nil {
		p.replayClient = newFeishuReplayClient(p.appID, p.appSecret, p.domain)
	}
	return p.replayClient
}

func newFeishuReplayClient(appID, appSecret, domain string) *lark.Client {
	var opts []lark.ClientOptionFunc

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Look up the embedded code in Feishu docs — 10003/10004 mean credentials are wrong.
  2. Re-copy app_id/app_secret from the Feishu developer console into config.toml and restart.
  3. Confirm the app type (self-built vs store) matches the token endpoint being used.
  4. Verify the correct domain (Feishu vs Lark) matches where the app is registered.

Example fix

// before
appSecret = "old-secret"
// after
# config.toml
[platforms.feishu]
app_id = "cli_xxx"
app_secret = "<current secret from developer console>"
Defensive patterns

Strategy: try-catch

Validate before calling

// verify credentials before deploying
token, err := fetchFreshTenantAccessToken(ctx)
if err != nil && strings.Contains(err.Error(), "code=10003") {
	return errors.New("invalid app_id")
}

Try / catch

token, err := p.fetchFreshTenantAccessToken(ctx)
if err != nil {
	var code int
	if extractFeishuCode(err, &code) && (code == 10003 || code == 10004) {
		return fmt.Errorf("feishu credentials rejected (code=%d): fix config.toml", code)
	}
	return err
}

Prevention

When it happens

Trigger: GetTenantAccessTokenBySelfBuiltApp returns a response with code != 0 — most commonly code 10003 (invalid app_id) or 10004 (invalid app_secret) — during the token-refresh retry path.

Common situations: Wrong or rotated app_secret in config.toml, app deleted/disabled in the Feishu developer console, using a Lark (open.larksuite.com) app against Feishu endpoints or vice versa, or store-app credentials used with a self-built token endpoint.

Related errors


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