chenhg5/cc-connect · error

%s: %s failed after token refresh attempt: %w (original erro

Error message

%s: %s failed after token refresh attempt: %w (original error: %v)

What it means

Raised by withFreshTenantAccessTokenRetry: the original API call failed with an invalid-tenant-access-token error, a fresh token fetch was attempted, but fetching the new token itself failed. The error chains both the refresh failure (%w) and the original API error for diagnosis.

Source

Thrown at platform/feishu/feishu.go:4096

				return fmt.Errorf("%s: %s api call: %w", p.tag(), op, err)
			}
			if !resp.Success() {
				return fmt.Errorf("%s: %s failed code=%d msg=%s", p.tag(), op, resp.Code, resp.Msg)
			}
			return nil
		})
	})
}

func (p *Platform) withFreshTenantAccessTokenRetry(ctx context.Context, operation string, fn feishuRequestFunc) error {
	err := fn(p.client)
	if !isTenantAccessTokenInvalid(err) {
		return err
	}

	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) == "" {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Inspect the wrapped refreshErr: if it's a network error, check connectivity to the Feishu token endpoint.
  2. Verify app_id/app_secret are still valid and unchanged in config.toml.
  3. Check the app is enabled and not deactivated in the Feishu developer console.
  4. Restart the service after fixing credentials so cached state is rebuilt.

Example fix

// before
return fmt.Errorf("%s: %s failed after token refresh attempt: %w (original error: %v)", p.tag(), operation, refreshErr, err)
// after
slog.Error(p.tag()+": token refresh failed", "operation", operation, "refreshErr", refreshErr, "originalErr", err)
return fmt.Errorf("%s: %s failed after token refresh attempt: %w (original error: %v)", p.tag(), operation, refreshErr, err)
Defensive patterns

Strategy: retry

Validate before calling

// startup credential check
if _, err := fetchFreshTenantAccessToken(ctx); err != nil {
	return fmt.Errorf("invalid feishu credentials: %w", err)
}

Try / catch

err := doFeishuCall(ctx)
if err != nil && strings.Contains(err.Error(), "token refresh attempt") {
	// credentials invalid or auth endpoint down: alert operator, do not hot-retry
	notifyOps(err)
}

Prevention

When it happens

Trigger: An Im.Message reply/create call fails with isTenantAccessTokenInvalid(err)==true, and the subsequent p.fetchFreshTenantAccessToken(ctx) returns an error (network failure or API rejection while obtaining the token).

Common situations: App secret revoked or rotated in the Feishu console while the service runs, Feishu auth endpoint unreachable, or app disabled — token refresh is impossible so the original token-expiry error persists.

Related errors


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