MCPcopy Create free account
hub / github.com/IIIIQIIII/claude-code / shouldRetry

Function shouldRetry

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

Source from the content-addressed store, hash-verified

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

Callers 1

withRetryFunction · 0.85

Calls 9

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

Tested by

no test coverage detected