Tencent/WeKnora · error
reload MCP OAuth token before refresh: %w
Error message
reload MCP OAuth token before refresh: %w
What it means
Wraps a repository error that occurred while reloading the stored OAuth token immediately after acquiring the refresh lease, before performing the refresh. refreshAsLeaseOwner must read current token state to decide whether another owner already rotated it; a storage failure here aborts the refresh with this wrapped error.
Source
Thrown at internal/mcp/oauth_lifecycle.go:198
}
}
func (r *oauthRuntime) refreshAsLeaseOwner(
ctx context.Context, observed *types.MCPOAuthToken, leaseID string, override *transport.OAuthHandler,
) error {
defer func() {
releaseCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 5*time.Second)
defer cancel()
if err := r.repo.ReleaseTokenRefreshLease(
releaseCtx, r.tenantID, r.principal, r.serviceID, leaseID,
); err != nil {
logger.GetLogger(releaseCtx).Warnf("failed to release MCP OAuth refresh lease: %v", err)
}
}()
current, err := r.repo.GetTokenForPrincipal(ctx, r.tenantID, r.principal, r.serviceID)
if err != nil {
return fmt.Errorf("reload MCP OAuth token before refresh: %w", err)
}
if current == nil || current.AccessToken == "" {
return &OAuthReauthorizationRequiredError{Reason: "no token is stored"}
}
// Another owner may have completed a refresh immediately before this lease
// was acquired. Never consume its newly rotated refresh token unnecessarily.
if oauthTokenMaterialChanged(current, observed) &&
(current.ExpiresAt.IsZero() || current.ExpiresAt.After(time.Now().Add(oauthRefreshSkew))) {
return nil
}
if current.RefreshToken == "" {
return r.invalidateToken(ctx, false, "no refresh token is available")
}
handler := override
if handler == nil {
handler = r.handler
}View on GitHub (pinned to 988cbb0330)
Solutions
- Check the wrapped cause for DB connectivity/auth errors and fix the database connection
- Re-run the operation; the lease is released via defer and can be safely re-acquired
- Ensure the DB user/credentials used by the repo are valid and not expired
- Increase context timeout so lease wait + reload fits within the deadline
Example fix
// before
tok, err := rt.EnsureFresh(ctx, tenantID, principal, serviceID)
if err != nil { return err }
// after: distinguish transient storage errors and retry
if err != nil {
if isTransientDBError(err) {
return retryWithBackoff(ctx, func() error {
tok, err = rt.EnsureFresh(ctx, tenantID, principal, serviceID); return err
})
}
return err
} Defensive patterns
Strategy: retry
Validate before calling
if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("token store unavailable before refresh: %w", err)
} Try / catch
err := rt.Refresh(ctx, tenantID, principal, serviceID)
if err != nil && strings.Contains(err.Error(), "reload MCP OAuth token before refresh") && isTransient(err) {
time.Sleep(backoff)
err = rt.Refresh(ctx, tenantID, principal, serviceID)
}
if err != nil {
var reauth *mcp.OAuthReauthorizationRequiredError
if errors.As(err, &reauth) { return startReauth(ctx, reauth) }
return err
} Prevention
- Ensure the request context outlives the lease wait plus reload
- Validate DB credentials after any secret rotation
- Set connection pool limits appropriate to concurrent refresh load
- Add retry-once logic for transient DB errors
When it happens
Trigger: refreshAsLeaseOwner acquires the refresh lease, calls repo.GetTokenForPrincipal, and the repo returns an error (DB unavailable, context cancelled, query failure).
Common situations: Database failover during a refresh; connection pool exhaustion under concurrent refreshes; context deadline exceeded while waiting for the lease then reading; misconfigured DB credentials after rotation.
Related errors
- reload MCP OAuth token after concurrent refresh: %w
- claim MCP OAuth token refresh: %w
- delete invalid MCP OAuth token: %w
- delete invalid MCP OAuth client registration: %w
- failed to create chunk: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/457665f6b04708a2.
Report an issue: GitHub.