MCPcopy
hub / github.com/codeaashu/claude-code / shouldRetry

Function shouldRetry

src/services/api/withRetry.ts:696–787  ·  view source on GitHub ↗
(error: APIError)

Source from the content-addressed store, hash-verified

694}
695
696function shouldRetry(error: APIError): boolean {
697 // Never retry mock errors - they're from /mock-limits command for testing
698 if (isMockRateLimitError(error)) {
699 return false
700 }
701
702 // Persistent mode: 429/529 always retryable, bypass subscriber gates and
703 // x-should-retry header.
704 if (isPersistentRetryEnabled() && isTransientCapacityError(error)) {
705 return true
706 }
707
708 // CCR mode: auth is via infrastructure-provided JWTs, so a 401/403 is a
709 // transient blip (auth service flap, network hiccup) rather than bad
710 // credentials. Bypass x-should-retry:false — the server assumes we'd retry
711 // the same bad key, but our key is fine.
712 if (
713 isEnvTruthy(process.env.CLAUDE_CODE_REMOTE) &&
714 (error.status === 401 || error.status === 403)
715 ) {
716 return true
717 }
718
719 // Check for overloaded errors first by examining the message content
720 // The SDK sometimes fails to properly pass the 529 status code during streaming,
721 // so we need to check the error message directly
722 if (error.message?.includes('"type":"overloaded_error"')) {
723 return true
724 }
725
726 // Check for max tokens context overflow errors that we can handle
727 if (parseMaxTokensContextOverflowError(error)) {
728 return true
729 }
730
731 // Note this is not a standard header.
732 const shouldRetryHeader = error.headers?.get('x-should-retry')
733
734 // If the server explicitly says whether or not to retry, obey.
735 // For Max and Pro users, should-retry is true, but in several hours, so we shouldn't.
736 // Enterprise users can retry because they typically use PAYG instead of rate limits.
737 if (
738 shouldRetryHeader === 'true' &&
739 (!isClaudeAISubscriber() || isEnterpriseSubscriber())
740 ) {
741 return true
742 }
743
744 // Ants can ignore x-should-retry: false for 5xx server errors only.
745 // For other status codes (401, 403, 400, 429, etc.), respect the header.
746 if (shouldRetryHeader === 'false') {
747 const is5xxError = error.status !== undefined && error.status >= 500
748 if (!(process.env.USER_TYPE === 'ant' && is5xxError)) {
749 return false
750 }
751 }
752
753 if (error instanceof APIConnectionError) {

Callers 1

withRetryFunction · 0.85

Calls 10

isMockRateLimitErrorFunction · 0.85
isPersistentRetryEnabledFunction · 0.85
isTransientCapacityErrorFunction · 0.85
isEnvTruthyFunction · 0.85
isEnterpriseSubscriberFunction · 0.85
clearApiKeyHelperCacheFunction · 0.85
isOAuthTokenRevokedErrorFunction · 0.85
getMethod · 0.65
isClaudeAISubscriberFunction · 0.50

Tested by

no test coverage detected