From db2b75a27d9342e905fa018f359bdddfb7f29ef9 Mon Sep 17 00:00:00 2001 From: Will-hxw Date: Wed, 29 Apr 2026 06:42:50 +0800 Subject: [PATCH] feat(errors): improve rate limit error messages for AI agents When GitHub API returns a rate limit error, surface clear retry duration to the agent instead of burying it in raw HTTP strings. For RateLimitError: show "Retry after Xs" For AbuseRateLimitError: show "Retry after Xs" when RetryAfter is set, otherwise show "Wait before retrying" Fixes #2385 --- pkg/errors/error.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pkg/errors/error.go b/pkg/errors/error.go index d757651592..99c6d2bd5a 100644 --- a/pkg/errors/error.go +++ b/pkg/errors/error.go @@ -2,8 +2,10 @@ package errors import ( "context" + "errors" "fmt" "net/http" + "time" "github.com/github/github-mcp-server/pkg/utils" "github.com/google/go-github/v82/github" @@ -159,6 +161,27 @@ func NewGitHubAPIErrorResponse(ctx context.Context, message string, resp *github if ctx != nil { _, _ = addGitHubAPIErrorToContext(ctx, apiErr) // Explicitly ignore error for graceful handling } + + var rateLimitErr *github.RateLimitError + if errors.As(err, &rateLimitErr) { + retryIn := time.Until(rateLimitErr.Rate.Reset.Time).Round(time.Second) + return utils.NewToolResultError(fmt.Sprintf( + "%s: GitHub API rate limit exceeded. Retry after %v.", + message, retryIn)) + } + + var abuseErr *github.AbuseRateLimitError + if errors.As(err, &abuseErr) { + if abuseErr.RetryAfter != nil { + return utils.NewToolResultError(fmt.Sprintf( + "%s: GitHub secondary rate limit exceeded. Retry after %v.", + message, abuseErr.RetryAfter.Round(time.Second))) + } + return utils.NewToolResultError(fmt.Sprintf( + "%s: GitHub secondary rate limit exceeded. Wait before retrying.", + message)) + } + return utils.NewToolResultErrorFromErr(message, err) }