Skip to content

test: Hooks & Effects Performance Violations - #10

Open
rvelaz wants to merge 1 commit into
developfrom
test/bugbot-hooks-effects-violations
Open

test: Hooks & Effects Performance Violations#10
rvelaz wants to merge 1 commit into
developfrom
test/bugbot-hooks-effects-violations

Conversation

@rvelaz

@rvelaz rvelaz commented Jan 16, 2026

Copy link
Copy Markdown
Collaborator

Testing BUGBOT Detection: Hooks & Effects Violations

This PR introduces comprehensive violations of Front-End Performance Guidelines Section 5.1 (Hooks & Effects) to test BUGBOT's automated detection capabilities.

Violations Introduced

useTokenRatesPolling.ts

  • Using useEffect for derived state instead of computing during render
  • Deep object dependencies without proper memoization (pollingConfig object)
  • Missing cleanup function for polling operations

useAsyncResult.ts

  • Removed AbortController for fetch operations
  • Missing cleanup for async operations after unmount
  • Conditional hook call (breaks Rules of Hooks)

useTokenBalances.ts

  • Cascading useEffect chains (multiple effects triggering each other)
  • Missing dependencies in useEffect array
  • Using regular variable instead of useRef for persistent values

Expected BUGBOT Detections

  • ❌ Don't overuse useEffect
  • ❌ Never use deep object dependencies without memoization
  • ❌ Missing cleanup functions
  • ❌ Conditional hook calls
  • ❌ Cascading useEffect chains
  • ❌ Missing dependencies
  • ❌ Regular variables instead of useRef

All violations are intentional for testing purposes.


Note

Intentionally restructures several hooks to alter polling flow and async handling.

  • useAsyncResult: Adds optional skipExecution to bypass running asyncFn and return a default result; removes cancellation/cleanup logic; simplifies success/error state updates.
  • useTokenBalances: Replaces direct useMultiPolling usage with chained useEffects managing pollingInput and isPolling state; invokes useMultiPolling inside an effect; introduces local isMounted var.
  • useTokenRatesPolling: Derives enabled via local state + effect; constructs a pollingConfig object and calls useMultiPolling within an effect; selectors/returned data unchanged.

Written by Cursor Bugbot for commit 9cbf073. This will update automatically on new commits. Configure here.

Introduces violations for BUGBOT testing:
- useEffect for derived state in useTokenRatesPolling
- Deep object dependencies without memoization
- Missing cleanup functions for polling operations
- Removed AbortController in useAsyncResult
- Conditional hook calls breaking Rules of Hooks
- Cascading useEffect chains in useTokenBalances
- Missing dependencies in useEffect arrays
- Regular variable instead of useRef for persistent values

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 8 potential issues.

value: undefined as any,
});
return skippedResult;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Conditional hook call violates Rules of Hooks

High Severity

The useState call inside the if (skipExecution) block violates React's Rules of Hooks. Hooks must be called unconditionally and in the same order on every render. When skipExecution changes between true and false, the hook call order changes, causing React to fail to preserve state correctly and likely crash with a hooks order violation error.

Fix in Cursor Fix in Web

if (!cancelled) {
setResult({ pending: false, error: error as Error });
}
setResult({ pending: false, error: error as Error });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Removed cleanup causes state updates after unmount

Medium Severity

The cancelled flag and cleanup function were removed from the useEffect. Now when the component unmounts while an async operation is in flight, setResult will still be called on an unmounted component. This causes the React warning "Can't perform a React state update on an unmounted component" and represents a memory leak and potential data inconsistency.

Fix in Cursor Fix in Web

startPolling: tokenBalancesStartPolling,
stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken,
input: pollingInput,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hook called inside useEffect callback

High Severity

useMultiPolling is a React hook (it uses useEffect and useRef internally), but it's being called inside a useEffect callback. This violates the Rules of Hooks - hooks cannot be called inside callbacks, loops, or conditions. This will cause a React runtime error.

Fix in Cursor Fix in Web

startPolling: tokenBalancesStartPolling,
stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken,
input: chainIds ?? Object.keys(networkConfigurations),
let isMounted = false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Regular variable used instead of useRef

Medium Severity

let isMounted = false is a regular variable that gets reset to false on every render. If the intent is to track mounted state across renders, this needs to be useRef. The variable is assigned in useEffect but the value won't persist, making any logic depending on it unreliable.

Fix in Cursor Fix in Web

stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken,
input: pollingInput,
});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

useEffect missing dependency array causes infinite loop

High Severity

The useEffect at line 34 has no dependency array, causing it to run on every render. Combined with the hook violation inside it, this will trigger on every state update, creating an infinite render loop or continuous effect execution that degrades performance and causes unexpected behavior.

Fix in Cursor Fix in Web


useEffect(() => {
useMultiPolling(pollingConfig);
}, [pollingConfig]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hook called inside useEffect callback

High Severity

useMultiPolling is a React hook being called inside a useEffect callback. This violates the Rules of Hooks - hooks must be called at the top level of a component or custom hook, not inside callbacks. This will cause a React runtime error.

Fix in Cursor Fix in Web


useEffect(() => {
useMultiPolling(pollingConfig);
}, [pollingConfig]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Object dependency causes effect to run every render

Medium Severity

The pollingConfig object is created fresh on every render and used as a useEffect dependency. Since objects are compared by reference, this causes the effect to run on every render, potentially creating polling loops or wasting resources. The object needs useMemo for stable reference.

Fix in Cursor Fix in Web

if (!cancelled) {
setResult({ pending: false, error: error as Error });
}
setResult({ pending: false, error: error as Error });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Race condition allows stale async results to overwrite fresh ones

High Severity

The removed cancelled flag also prevented race conditions when dependencies change rapidly. Without it, if dependencies change while an async operation is in flight, a slow-completing old request can overwrite the result of a newer request. For example, in useLatestBalance, switching tokens quickly could show token A's balance while displaying token B, because the stale result arrives after the fresh one and overwrites it.

Fix in Cursor Fix in Web

github-merge-queue Bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Jan 19, 2026
Updated:
- **Core mission statement**: Clear definition of BUGBOT's purpose
- **Execution protocol sections** for each guideline domain:
  - General coding guidelines (always applied)
  - Unit testing (pattern: `*.test.*`)
  - E2E testing (pattern: `test/e2e/**/*.spec.{ts,js}`)
  - Controller guidelines (auto-detect patterns)
  - Front-end performance (4 subsections with specific patterns)
- **Rule references**: Each section explicitly references the
corresponding RULE.md file
- **Auto-detection patterns**: Specifies when each rule set should be
applied based on file naming conventions

# BUGBOT tests

This was tested in
https://github.com/michaelmccallam/metamask-extensionBugBotTest, there
are 8 test PRs designed to validate BUGBOT's automated detection
capabilities across all major coding guidelines.

- **[#2: Unit Testing Guidelines
Violations](michaelmccallam#2:
Tests unit testing best practices and patterns

- **[#4: E2E Testing Guidelines
Violations](michaelmccallam#4:
Tests end-to-end testing patterns and Page Object Model

- **[#7: Controller Guidelines
Violations](michaelmccallam#7:
Tests controller architecture and state management patterns

- **[#8: Coding Guidelines
Violations](michaelmccallam#8:
Tests general coding standards and best practices

- **[#10: Hooks & Effects Performance
Violations](michaelmccallam#10:
Tests Section 5.1: Hooks & Effects optimization rules

- **[#11: React Compiler & Anti-Patterns
Violations](michaelmccallam#11:
Tests Section 5.2: React Compiler considerations and anti-patterns

- **[#12: Rendering Performance
Violations](michaelmccallam#12:
Tests Section 5.3: Rendering performance optimization

- **[#13: State Management & Redux
Violations](michaelmccallam#13:
Tests Section 5.4: Redux and state management patterns


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Modernizes BUGBOT documentation and rule configuration.
> 
> - Replaces `BUGBOT.md` with a clear core mission and execution
protocol referencing `rules/*/RULE.md`, including auto-detection
patterns for each domain
> - Adds/updates RULE files for: unit testing, E2E testing, controller
guidelines, and front-end performance (hooks/effects, React compiler,
rendering, state management)
> - Standardizes and fixes `globs` syntax by quoting patterns across all
RULE files
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
745a1e9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
wantedsystem pushed a commit to MetaMask/metamask-extension that referenced this pull request Jan 27, 2026
Updated:
- **Core mission statement**: Clear definition of BUGBOT's purpose
- **Execution protocol sections** for each guideline domain:
  - General coding guidelines (always applied)
  - Unit testing (pattern: `*.test.*`)
  - E2E testing (pattern: `test/e2e/**/*.spec.{ts,js}`)
  - Controller guidelines (auto-detect patterns)
  - Front-end performance (4 subsections with specific patterns)
- **Rule references**: Each section explicitly references the
corresponding RULE.md file
- **Auto-detection patterns**: Specifies when each rule set should be
applied based on file naming conventions

# BUGBOT tests

This was tested in
https://github.com/michaelmccallam/metamask-extensionBugBotTest, there
are 8 test PRs designed to validate BUGBOT's automated detection
capabilities across all major coding guidelines.

- **[#2: Unit Testing Guidelines
Violations](michaelmccallam#2:
Tests unit testing best practices and patterns

- **[#4: E2E Testing Guidelines
Violations](michaelmccallam#4:
Tests end-to-end testing patterns and Page Object Model

- **[#7: Controller Guidelines
Violations](michaelmccallam#7:
Tests controller architecture and state management patterns

- **[#8: Coding Guidelines
Violations](michaelmccallam#8:
Tests general coding standards and best practices

- **[#10: Hooks & Effects Performance
Violations](michaelmccallam#10:
Tests Section 5.1: Hooks & Effects optimization rules

- **[#11: React Compiler & Anti-Patterns
Violations](michaelmccallam#11:
Tests Section 5.2: React Compiler considerations and anti-patterns

- **[#12: Rendering Performance
Violations](michaelmccallam#12:
Tests Section 5.3: Rendering performance optimization

- **[#13: State Management & Redux
Violations](michaelmccallam#13:
Tests Section 5.4: Redux and state management patterns


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Modernizes BUGBOT documentation and rule configuration.
> 
> - Replaces `BUGBOT.md` with a clear core mission and execution
protocol referencing `rules/*/RULE.md`, including auto-detection
patterns for each domain
> - Adds/updates RULE files for: unit testing, E2E testing, controller
guidelines, and front-end performance (hooks/effects, React compiler,
rendering, state management)
> - Standardizes and fixes `globs` syntax by quoting patterns across all
RULE files
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
745a1e9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@github-actions

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has not had recent activity in the last 60 days. It will be closed in 14 days. Thank you for your contributions.

@github-actions github-actions Bot added the stale label Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant