Skip to content

fix: cancel backend auto-approval timeout when auto-approve is toggled off mid-countdown#11439

Merged
daniel-lxs merged 1 commit intomainfrom
fix/auto-approve-countdown-cancel-on-toggle-off
Feb 12, 2026
Merged

fix: cancel backend auto-approval timeout when auto-approve is toggled off mid-countdown#11439
daniel-lxs merged 1 commit intomainfrom
fix/auto-approve-countdown-cancel-on-toggle-off

Conversation

@SannidhyaSah
Copy link
Collaborator

@SannidhyaSah SannidhyaSah commented Feb 12, 2026

Related GitHub Issue

Closes: N/A

Roo Code Task Context (Optional)

No Roo Code task context for this PR

Description

When a user disables auto-approve while a followup question countdown timer is actively running, only the visual timer in the UI was removed — the backend setTimeout in Task.ts continued running and eventually auto-submitted the answer anyway.

Root cause: ChatView.tsx was not passing the onFollowUpUnmount callback to ChatRow, so when FollowUpSuggest's useEffect cleanup function fired (due to autoApprovalEnabled changing to false), the onCancelAutoApproval?.() call was a no-op since the callback was undefined. The backend was never notified to cancel its pending timeout.

Fix:

  1. Added a handleFollowUpUnmount callback in ChatView.tsx that sends a cancelAutoApproval message to the backend
  2. Passed it as the onFollowUpUnmount prop to ChatRow

Now the full cancellation chain works:
FollowUpSuggest useEffect cleanup → onCancelAutoApproval()handleFollowUpUnmount()vscode.postMessage({ type: "cancelAutoApproval" })webviewMessageHandler.tstask.cancelAutoApprovalTimeout() → clears the backend setTimeout

Test Procedure

  1. Automated tests:

    • Added 2 new tests in FollowUpSuggest.spec.tsx:
      • should call onCancelAutoApproval when autoApprovalEnabled changes to false during countdown
      • should call onCancelAutoApproval when alwaysAllowFollowupQuestions changes to false during countdown
    • All 20 FollowUpSuggest tests pass
    • All 24 ChatView tests pass
    • All 5 ChatRow tests pass
    • Full pnpm test suite: 5428 tests passed, 46 skipped
  2. Manual testing steps:

    • Enable auto-approve with follow-up questions auto-approve enabled
    • Send a message that triggers a follow-up question with suggestions
    • While the countdown timer is visible on the first suggestion, toggle auto-approve off
    • Verify: The countdown timer disappears AND the answer is NOT auto-submitted after the original timeout duration

Pre-Submission Checklist

  • Issue Linked: This PR addresses a bug in the auto-approve countdown cancellation flow.
  • Scope: Changes are focused on fixing the missing callback propagation (2 files changed).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New tests added to cover the toggle-off-mid-countdown scenario.
  • Documentation Impact: No documentation updates required.
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

No UI changes in this PR — the fix ensures existing UI behavior (timer disappearing) is properly synchronized with the backend.

Documentation Updates

  • No documentation updates are required.

Additional Notes

Files changed:

  • webview-ui/src/components/chat/ChatView.tsx — Added handleFollowUpUnmount callback and passed it as onFollowUpUnmount prop to ChatRow
  • webview-ui/src/components/chat/__tests__/FollowUpSuggest.spec.tsx — Added 2 regression tests for the toggle-off-mid-countdown scenario

Get in Touch

Sa

…d off mid-countdown

When a user disables auto-approve while a followup countdown timer is
running, only the visual timer was removed but the backend setTimeout
in Task.ts continued running and eventually auto-submitted the answer.

Root cause: ChatView.tsx was not passing the onFollowUpUnmount callback
to ChatRow, so FollowUpSuggest's cleanup function could not notify the
backend to cancel its pending timeout.

Fix: Add handleFollowUpUnmount callback in ChatView that sends
cancelAutoApproval message to the backend, and pass it as
onFollowUpUnmount prop to ChatRow. Now when FollowUpSuggest's useEffect
cleanup fires (due to autoApprovalEnabled changing to false), it calls
onCancelAutoApproval -> handleFollowUpUnmount -> cancelAutoApproval
message -> task.cancelAutoApprovalTimeout() clearing the backend timer.
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Feb 12, 2026
@roomote
Copy link
Contributor

roomote bot commented Feb 12, 2026

Rooviewer Clock   See task

Reviewed with no issues found. The fix correctly wires up the missing onFollowUpUnmount callback from ChatView to ChatRow, completing the cancellation chain so the backend setTimeout is properly cleared when auto-approve is toggled off mid-countdown. All 20 FollowUpSuggest and 24 ChatView tests pass.

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

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Feb 12, 2026
@daniel-lxs daniel-lxs merged commit 6c9ff49 into main Feb 12, 2026
18 checks passed
@daniel-lxs daniel-lxs deleted the fix/auto-approve-countdown-cancel-on-toggle-off branch February 12, 2026 15:38
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Feb 12, 2026
0xMink added a commit to 0xMink/Roo-Code that referenced this pull request Feb 12, 2026
When auto-approve is toggled off mid-countdown, the backend setTimeout
could still fire and auto-commit a selection. PR RooCodeInc#11439 fixed the UI
cleanup wiring; this hardens the backend independently.

- webviewMessageHandler: cancel pending timeout when autoApprovalEnabled
  is toggled off
- Task.ts: timeout callback re-checks autoApprovalEnabled and ask
  staleness before committing, with full try/catch to prevent unhandled
  rejections from the async callback
- Added 4 backend regression tests covering explicit cancellation,
  defensive gate, superseded ask, and happy-path auto-select

Closes RooCodeInc#11445
daniel-lxs pushed a commit that referenced this pull request Feb 13, 2026
…d off mid-countdown (#11439)

Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
daniel-lxs pushed a commit that referenced this pull request Feb 13, 2026
…d off mid-countdown (#11439)

Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
daniel-lxs pushed a commit that referenced this pull request Feb 13, 2026
…d off mid-countdown (#11439)

Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
daniel-lxs added a commit that referenced this pull request Feb 13, 2026
* fix: cancel backend auto-approval timeout when auto-approve is toggled off mid-countdown (#11439)

Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>

* fix: prevent chat history loss during cloud/settings navigation (#11371) (#11372)

Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>

* fix: preserve pasted images in chatbox during chat activity (#11375)

Co-authored-by: Roo Code <roomote@roocode.com>

* fix: resolve chat scroll anchoring and task-switch scroll race condit… (#11385)

* fix: avoid zsh process-substitution false positives in assignments (#11365)

* fix(editor): make tab close best-effort in DiffViewProvider.open (#11363)

* fix(checkpoints): canonicalize core.worktree comparison to prevent Windows path mismatch failures (#11346)

* fix: prevent double notification sound playback (#11283)

* fix: prevent false unsaved changes prompt with OpenAI Compatible headers (#8230) (#11334)

fix: prevent false unsaved changes prompt with OpenAI Compatible headers

Mark automatic header syncs in ApiOptions and OpenAICompatible as
non-user actions (isUserAction: false) and enhance SettingsView change
detection to skip automatic syncs with semantically equal values.

Root cause: two components (ApiOptions and OpenAICompatible) manage
openAiHeaders state and automatically sync it back on mount/remount.
These syncs were treated as user changes, triggering a false dirty state.

Co-authored-by: Robert McIntyre <robertjmcintyre@users.noreply.github.com>

* fix: remove noisy console.warn logs from NativeToolCallParser (#11264)

Remove two console.warn messages that fire excessively when loading tasks
from history:
- 'Attempting to finalize unknown tool call' in finalizeStreamingToolCall()
- 'Received chunk for unknown tool call' in processStreamingChunk()

The defensive null-return behavior is preserved; only the log output is removed.

* refactor: remove footgun prompting (file-based system prompt override) (#11387)

* refactor: delete orphaned per-provider caching transform files (#11388)

* feat: add disabledTools setting to globally disable native tools (#11277)

* feat: add disabledTools setting to globally disable native tools

Add a disabledTools field to GlobalSettings that allows disabling specific
native tools by name. This enables cloud agents to be configured with
restricted tool access.

Schema:
- Add disabledTools: z.array(toolNamesSchema).optional() to globalSettingsSchema
- Add disabledTools to organizationDefaultSettingsSchema.pick()
- Add disabledTools to ExtensionState Pick type

Prompt generation (tool filtering):
- Add disabledTools to BuildToolsOptions interface
- Pass disabledTools through filterSettings to filterNativeToolsForMode()
- Remove disabled tools from allowedToolNames set in filterNativeToolsForMode()

Execution-time validation (safety net):
- Extract disabledTools from state in presentAssistantMessage
- Convert disabledTools to toolRequirements format for validateToolUse()

Wiring:
- Add disabledTools to ClineProvider getState() and getStateToPostToWebview()
- Pass disabledTools to all buildNativeToolsArrayWithRestrictions() call sites

EXT-778

* fix: check toolRequirements before ALWAYS_AVAILABLE_TOOLS

Moves the toolRequirements check before the ALWAYS_AVAILABLE_TOOLS
early-return in isToolAllowedForMode(). This ensures disabledTools
can block always-available tools (switch_mode, new_task, etc.) at
execution time, making the validation layer consistent with the
filtering layer.

* feat: add support for .agents/skills directory (#11181)

* feat: add support for .agents/skills directory

This change adds support for discovering skills from the .agents/skills
directory, following the Agent Skills convention for sharing skills
across different AI coding tools.

Priority order (later entries override earlier ones):
1. Global ~/.agents/skills (shared across AI coding tools, lowest priority)
2. Project .agents/skills
3. Global ~/.roo/skills (Roo-specific)
4. Project .roo/skills (highest priority)

Changes:
- Add getGlobalAgentsDirectory() and getProjectAgentsDirectoryForCwd()
  functions to roo-config
- Update SkillsManager.getSkillsDirectories() to include .agents/skills
- Update SkillsManager.setupFileWatchers() to watch .agents/skills
- Add tests for new functionality

* fix: clarify skill priority comment to match actual behavior

* fix: clarify skill priority comment to explain Map.set replacement mechanism

---------

Co-authored-by: Roo Code <roomote@roocode.com>

* feat(history): render nested subtasks as recursive tree (#11299)

* feat(history): render nested subtasks as recursive tree

* fix(lockfile): resolve missing ai-sdk provider entry

* fix: address review feedback — dedupe countAll, increase SubtaskRow max-h

- HistoryView: replace local countAll with imported countAllSubtasks from types.ts
- SubtaskRow: increase nested children max-h from 500px to 2000px to match TaskGroupItem

* perf(refactor): consolidate getState calls in resolveWebviewView (#11320)

* perf(refactor): consolidate getState calls in resolveWebviewView

Replace three separate this.getState().then() calls with a single
await this.getState() and destructuring. This avoids running the
full getState() method (CloudService calls, ContextProxy reads, etc.)
three times during webview view resolution.

* fix: keep getState consolidation non-blocking to avoid delaying webview render

---------

Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>

* fix: harden command auto-approval against inline JS false positives (#11382)

* feat: rename search_and_replace tool to edit and unify edit-family UI (#11296)

* Revert "refactor: delete orphaned per-provider caching transform files (#11388)"

This reverts commit 13a45b0.

* chore: regenerate built-in-skills.ts with updated formatting

* fix: add missing maxReadFileLine property to test baseState

The ExtensionState type now requires maxReadFileLine property (added in commit 63e3f76).
Update the test to include this property with the default value of -1 (unlimited reading).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add pnpm serve command for code-server development (#10964)

Co-authored-by: Roo Code <roomote@roocode.com>

* chore: remove Feature Request from issue template options (#11141)

Co-authored-by: Roo Code <roomote@roocode.com>

* refactor(docs-extractor): simplify mode to focus on raw fact extraction (#11129)

* Add cli support for linux (#11167)

* fix: replace heredocs with echo statements in cli-release workflow (#11168)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* Drop MacOS-13 cli support (#11169)

* fix(cli): correct example in install script (#11170)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add Kimi K2.5 model to Fireworks provider (#11177)

* feat(cli): improve dev experience and roo provider API key support (#11203)

- Allow --api-key and ROO_API_KEY env var for the roo provider instead of
  requiring cloud auth token
- Switch dev/start scripts to use tsx for running directly from source
  without building first
- Fix path resolution (version.ts, extension.ts, extension-host.ts) to
  work from both source and bundled locations
- Disable debug log file (~/.roo/cli-debug.log) unless --debug is passed
- Update README with complete env var table and dev workflow docs

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>

* Roo Code CLI v0.0.50 (#11204)

* Roo Code CLI v0.0.50

* docs(cli): add --exit-on-error to changelog

---------

Co-authored-by: Roo Code <roomote@roocode.com>

* feat(cli): update default model from Opus 4.5 to Opus 4.6 (#11273)

Co-authored-by: Roo Code <roomote@roocode.com>

* feat(web): replace Roomote Control with Linear Integration in cloud features grid (#11280)

Co-authored-by: Roo Code <roomote@roocode.com>

* Add linux-arm64 for the roo cli (#11314)

* chore: clean up repo-facing mode rules (#11410)

* Make CLI auto-approve by default with require-approval opt-in (#11424)

Co-authored-by: Roo Code <roomote@roocode.com>

* Add new code owners to CODEOWNERS file

* Update next.js (#11108)

* feat(web): Replace bespoke navigation menu with shadcn navigation menu (#11117)

Co-authored-by: Roo Code <roomote@roocode.com>

---------

Co-authored-by: SannidhyaSah <sah_sannidhya@outlook.com>
Co-authored-by: Sannidhya <sann@Sannidhyas-MacBook-Pro.local>
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: Hannes Rudolph <hrudolph@gmail.com>
Co-authored-by: 0xMink <dennis@dennismink.com>
Co-authored-by: Robert McIntyre <robertjmcintyre@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
Co-authored-by: Chris Estreich <cestreich@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants