-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
name: Bug Report
description: Multiple potential memory leaks in CodeBlock component due to unmanaged async operations and timeouts.
labels: ["bug", "memory-leak", "auto-generated", "react", "async", "setTimeout"]
body:
-
type: markdown
attributes:
value: |
Thanks for your report! Please check existing issues first:
👉 https://github.com/RooCodeInc/Roo-Code/issues -
type: input
id: version
attributes:
label: App Version
description: What version of Roo Code are you using? (e.g., v3.3.1)
value: "Latest (auto-detected)"
validations:
required: true -
type: dropdown
id: provider
attributes:
label: API Provider
options:
- Anthropic
- AWS Bedrock
- Chutes AI
- DeepSeek
- Glama
- Google Gemini
- Google Vertex AI
- Groq
- Human Relay Provider
- LiteLLM
- LM Studio
- Mistral AI
- Ollama
- OpenAI
- OpenAI Compatible
- OpenRouter
- Requesty
- Unbound
- VS Code Language Model API
- xAI (Grok)
- Not Applicable / Other
default_value: Not Applicable / Other
validations:
required: true -
type: input
id: model
attributes:
label: Model Used
description: Exact model name (e.g., Claude 3.7 Sonnet). Use N/A if irrelevant.
value: "N/A"
validations:
required: true -
type: textarea
id: steps
attributes:
label: 🔁 Steps to Reproduce
description: |
Help us see what you saw. Give clear, numbered steps:1. Setup (OS, extension version, settings) 2. Exact actions (clicks, input, files, commands) 3. What happened after each step Think like you're writing a recipe. Without this, we can't reproduce the issue.value: |
1. Setup: Any OS, latest Roo Code extension version.
2. Exact actions:
a. Render aCodeBlockcomponent (e.g., in a chat message).
b. Cause theCodeBlockcomponent to unmount while asynchronous operations are pending. This can occur in several scenarios:
i. During syntax highlighting (useEffecthook at original line 247 inwebview-ui/src/components/common/CodeBlock.tsx).
ii. WhenhighlightedCodechanges, triggering asetTimeoutto update button positions (useEffecthook at original line 456,setTimeoutat original line 459).
iii. When the collapse/expand button is clicked, triggering nestedsetTimeoutcalls (onClickhandler at original line 684,setTimeoutcalls at original lines 694 and 699).
3. What happened after each step: If the component unmounts before these asynchronous operations or timeouts complete, React warnings ("Can't perform a React state update on an unmounted component") may appear, and functions may attempt to operate on DOM elements that no longer exist. This indicates potential memory leaks.
validations:
required: true -
type: textarea
id: what-happened
attributes:
label: 💥 Outcome Summary
description: |
Recap what went wrong in one or two lines.Example: "Expected code to run, but got an empty response and no error."placeholder: Expected ___, but got ___.
value: |
Expected the component to clean up without errors, but React state update warnings on an unmounted component and potential errors from DOM manipulation on unmounted refs can occur, indicating memory leaks.
validations:
required: true -
type: textarea
id: logs
attributes:
label: 📄 Relevant Logs or Errors (Optional)
description: Paste API logs, terminal output, or errors here. Use triple backticks () for code formatting. value: |
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in CodeBlock (created by ...)
...
```
render: shell
🔍 Summary of Issues:
The CodeBlock component in webview-ui/src/components/common/CodeBlock.tsx has multiple instances where asynchronous operations or setTimeout calls are not properly cleaned up if the component unmounts before their completion. This can lead to React state update warnings and potential memory leaks.
1. Async Syntax Highlighting (Original Line 247, CodeBlock_247):
- The
useEffecthook for syntax highlighting callssetHighlightedCodeafterawaiting Shiki operations. - Leak: If unmounted during
await,setHighlightedCodeacts on an unmounted component.
2. setTimeout for Button Position Update (Original Line 459, CodeBlock_459):
- A
useEffecthook dependent onhighlightedCodeusessetTimeoutto callupdateCodeBlockButtonPosition. - Leak: Timeout not cleared on unmount or subsequent
highlightedCodechanges, potentially callingupdateCodeBlockButtonPositionon an unmounted component.
3. Nested setTimeout in Collapse/Expand Handler (Original Lines 694, 699, CodeBlock_694):
- The
onClickhandler for the collapse/expand button uses nestedsetTimeoutcalls forscrollIntoViewandupdateCodeBlockButtonPosition. - Leak: These timeouts are not cleared on unmount, leading to potential DOM manipulation on non-existent elements.
✅ Consolidated Fix:
The following fixes have been applied:
-
Mounted State Ref (
isMountedRef):- A
useRef(isMountedRef) is used to track the component's mounted status. - It's set to
trueon mount andfalsein auseEffectcleanup function. - All asynchronous
setHighlightedCodecalls (related toCodeBlock_247) are now conditional onisMountedRef.current.
- A
-
Timeout Management for Button Position (
buttonPositionTimeoutRef):- A
useRef(buttonPositionTimeoutRef) stores the ID of thesetTimeoutforupdateCodeBlockButtonPosition(related toCodeBlock_459). - Any existing timeout is cleared before a new one is set.
- The timeout is cleared in the
useEffect's cleanup function.
- A
-
Timeout Management for Collapse/Expand (
collapseTimeout1Ref,collapseTimeout2Ref):- Two
useRefs (collapseTimeout1Ref,collapseTimeout2Ref) store the IDs of the nestedsetTimeouts in the collapse/expand handler (related toCodeBlock_694). - Existing timeouts are cleared within the
onClickhandler before new ones are set. - A dedicated
useEffecthook with an empty dependency array ensures these timeouts are cleared on component unmount. - Checks for
codeBlockRef.currentare added before DOM manipulations within timeout callbacks.
- Two
These changes ensure that asynchronous operations and timeouts are properly managed and cleaned up, preventing state updates or DOM manipulations on unmounted components.
🧪 Combined Confidence: 90%
Metadata
Metadata
Assignees
Labels
Type
Projects
Status