Tencent/WeKnora · error
delete invalid MCP OAuth token: %w
Error message
delete invalid MCP OAuth token: %w
What it means
Wraps a repository error from DeleteTokenForPrincipal when the runtime decides the stored OAuth token is invalid and must be removed. The deletion is the first step of invalidation so the next access triggers reauthorization; if the delete fails, the token remains and the error propagates to refreshAsLeaseOwner.
Source
Thrown at internal/mcp/oauth_lifecycle.go:243
permanent, resetClient := permanentRefreshFailure(refreshErr)
if permanent {
return r.invalidateToken(ctx, resetClient, "the refresh token or OAuth client is no longer valid")
}
return &OAuthRefreshTemporaryError{Err: refreshErr}
}
func oauthTokenMaterialChanged(current, observed *types.MCPOAuthToken) bool {
if current == nil || observed == nil {
return current != observed
}
return current.AccessToken != observed.AccessToken ||
current.RefreshToken != observed.RefreshToken ||
!current.ExpiresAt.Equal(observed.ExpiresAt)
}
func (r *oauthRuntime) invalidateToken(ctx context.Context, resetClient bool, reason string) error {
if err := r.repo.DeleteTokenForPrincipal(ctx, r.tenantID, r.principal, r.serviceID); err != nil {
return fmt.Errorf("delete invalid MCP OAuth token: %w", err)
}
if resetClient {
if err := r.repo.DeleteClient(ctx, r.tenantID, r.serviceID); err != nil {
return fmt.Errorf("delete invalid MCP OAuth client registration: %w", err)
}
}
return &OAuthReauthorizationRequiredError{Reason: reason}
}
func permanentRefreshFailure(err error) (permanent bool, resetClient bool) {
var oauthErr transport.OAuthError
if errors.As(err, &oauthErr) {
switch strings.ToLower(oauthErr.ErrorCode) {
case "invalid_grant", "invalid_token", "bad_refresh_token", "expired_token":
return true, false
case "invalid_client", "unauthorized_client":
return true, true
}View on GitHub (pinned to 988cbb0330)
Solutions
- Check DB write permissions: the repo user needs DELETE on the token table
- Fix database connectivity / read-only state and retry the operation
- Manually delete the stale token row so the user is prompted to re-authorize
- Check the wrapped cause for context cancellation and increase the deadline
Example fix
// before
err := rt.InvalidateToken(ctx, tenantID, principal, serviceID)
// after: log-and-fallback if delete fails, since reauth is the goal
if err != nil && isReadOnlyDB(err) {
log.Warnf("could not delete invalid token; forcing reauth flag instead: %v", err)
return repo.MarkTokenNeedsReauth(ctx, tenantID, principal, serviceID)
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure DB is writable before triggering refresh flows
if err := db.PingContext(ctx); err != nil { return err }
if readOnly, _ := dbIsReadOnly(ctx); readOnly { return fmt.Errorf("db read-only") } Try / catch
if err := rt.Refresh(ctx, tenantID, principal, serviceID); err != nil {
var reauth *mcp.OAuthReauthorizationRequiredError
if errors.As(err, &reauth) {
// invalidation delete may have failed; check and clean up manually
if delErr := repo.DeleteTokenForPrincipal(ctx, tenantID, principal, serviceID); delErr != nil {
log.Errorf("token delete failed, manual cleanup needed: %v", delErr)
}
return redirectToReauth(reauth)
}
return err
} Prevention
- Grant the app DB user DELETE privileges on token tables
- Monitor for read-only replica routing on write paths
- Alert on any 'delete invalid MCP OAuth token' occurrences
- Periodically reconcile orphaned invalid tokens
When it happens
Trigger: invalidateToken is invoked after permanentRefreshFailure classifies the refresh error as permanent, and repo.DeleteTokenForPrincipal returns an error (DB down, write permission denied, read-only replica, context cancelled).
Common situations: Database in read-only mode; DB user lacks DELETE privilege on the token table; connection dropped mid-write; disk full on the database host.
Related errors
- reload MCP OAuth token after concurrent refresh: %w
- reload MCP OAuth token before refresh: %w
- delete invalid MCP OAuth client registration: %w
- failed to create chunk: %w
- list %s pages: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/0c32389988be1e50.
Report an issue: GitHub.