Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Dec 19, 2025

This PR attempts to address Issue #10106. Feedback and guidance are welcome.

Problem

When API providers (Roo Cloud, OpenRouter, Requesty) return empty assistant responses while auto-approval is enabled, the system enters infinite retry loops with exponential backoff. This consumes tokens/credits indefinitely without user intervention.

As noted by @uaktags in the issue, this is a systemic issue affecting multiple providers, not just a single provider.

Solution

This PR adds a centralized fix in Task.ts that benefits all providers:

  1. New constant: MAX_EMPTY_RESPONSE_RETRIES = 3 - limits retries for empty assistant response errors
  2. Retry limit check: Before auto-retrying, checks if the retry count has exceeded the limit
  3. Graceful fallback: When limit is reached, falls back to user prompt instead of continuing to auto-retry indefinitely

This follows the same pattern as the existing MAX_CONTEXT_WINDOW_RETRIES limit.

Changes

  • src/core/task/Task.ts:
    • Added MAX_EMPTY_RESPONSE_RETRIES constant (line 140)
    • Added retry limit check before auto-retry logic (lines 3312-3319)

Testing

  • TypeScript compilation passes
  • ESLint passes
  • The fix is in the same code path that handles all providers, ensuring consistent behavior

Related

This fix addresses Issue #10106 where the system enters infinite retry loops
when API providers (Roo Cloud, OpenRouter, Requesty) return empty assistant
responses while auto-approval is enabled.

Changes:
- Add MAX_EMPTY_RESPONSE_RETRIES constant (3 retries)
- Add retry limit check before auto-retry logic
- When limit is reached, fall back to user prompt instead of continuing
  to auto-retry indefinitely

This is a centralized fix in Task.ts that benefits all providers, addressing
the systemic nature of the issue rather than implementing provider-specific
safeguards.
@roomote
Copy link
Contributor Author

roomote bot commented Dec 19, 2025

Rooviewer Clock   See task on Roo Cloud

Review completed. Found 1 issue that needs to be addressed before merging.

  • The if-else-if-else structure causes silent failure instead of prompting user when retry limit is reached (see inline comment)

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

Comment on lines +3311 to +3318
// Check if we've exceeded maximum retries for empty responses
const emptyResponseRetryCount = currentItem.retryAttempt ?? 0
if (emptyResponseRetryCount >= MAX_EMPTY_RESPONSE_RETRIES) {
console.warn(
`[Task#${this.taskId}.${this.instanceId}] Empty response retry limit reached (${emptyResponseRetryCount}/${MAX_EMPTY_RESPONSE_RETRIES}). Falling back to user prompt.`,
)
// Fall through to manual retry prompt below
} else if (state?.autoApprovalEnabled) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "fall through" comment is misleading. Due to the if-else-if-else structure, when emptyResponseRetryCount >= MAX_EMPTY_RESPONSE_RETRIES is true, the code executes only the console.warn, then skips both the else if and else branches entirely, falling through to return false at line 3390. This means the user is NOT prompted when the retry limit is reached - the task silently returns false.

To actually fall through to the user prompt, restructure the condition:

Suggested change
// Check if we've exceeded maximum retries for empty responses
const emptyResponseRetryCount = currentItem.retryAttempt ?? 0
if (emptyResponseRetryCount >= MAX_EMPTY_RESPONSE_RETRIES) {
console.warn(
`[Task#${this.taskId}.${this.instanceId}] Empty response retry limit reached (${emptyResponseRetryCount}/${MAX_EMPTY_RESPONSE_RETRIES}). Falling back to user prompt.`,
)
// Fall through to manual retry prompt below
} else if (state?.autoApprovalEnabled) {
// Check if we've exceeded maximum retries for empty responses
const emptyResponseRetryCount = currentItem.retryAttempt ?? 0
if (state?.autoApprovalEnabled && emptyResponseRetryCount < MAX_EMPTY_RESPONSE_RETRIES) {

This way, when the retry limit is reached OR auto-approval is disabled, the code enters the else branch which prompts the user.

Fix it with Roo Code or mention @roomote and request a fix.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels.

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

[BUG] Unknown API Error: Please contact Roo Code support

3 participants