Detect race conditions, timing issues, and async bugs in frontend JavaScript/TypeScript code.
Detects race conditions, timing issues, and async bugs in frontend JavaScript/TypeScript code. Identifies stale closures, unmounted component updates, and missing cleanup in React/Vue/Svelte components.
/plugin marketplace add KreativReason/merged-end-to-end-ai-dpp---e2e-cli/plugin install kreativreason-e2e-pipeline@kreativreason-marketplaceDetect race conditions, timing issues, and async bugs in frontend JavaScript/TypeScript code.
// Bad: Stale closure in useEffect
function SearchComponent() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
useEffect(() => {
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(data => setResults(data)); // Race condition!
}, [query]);
}
// Good: Abort controller
function SearchComponent() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
useEffect(() => {
const controller = new AbortController();
fetch(`/api/search?q=${query}`, { signal: controller.signal })
.then(res => res.json())
.then(data => setResults(data))
.catch(err => {
if (err.name !== 'AbortError') throw err;
});
return () => controller.abort();
}, [query]);
}
// Bad: State update after unmount
function DataLoader() {
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(setData); // May update unmounted component!
}, []);
}
// Good: Track mounted state
function DataLoader() {
const [data, setData] = useState(null);
useEffect(() => {
let mounted = true;
fetchData().then(result => {
if (mounted) setData(result);
});
return () => { mounted = false; };
}, []);
}
// Bad: React 18 Strict Mode double fetch
useEffect(() => {
fetch('/api/data'); // Runs twice in dev!
}, []);
// Good: Proper cleanup or React Query/SWR
const { data } = useQuery(['data'], fetchData);
| Check | Description |
|---|---|
| Stale closures | Async callbacks with stale state |
| Unmount updates | State updates after unmount |
| Missing cleanup | useEffect without cleanup |
| Concurrent updates | Overlapping async operations |
| Event handler races | Click handlers with async |
| Debounce/throttle | Missing rate limiting |
{
"artifact_type": "race_condition_review",
"status": "pass|warn|fail",
"data": {
"target": "PR #123",
"framework": "React 18",
"findings": [
{
"id": "RACE-001",
"severity": "high",
"type": "stale_closure",
"title": "Stale Closure in useEffect",
"file": "src/components/Search.tsx",
"line": 23,
"description": "Async callback may use outdated query value",
"pattern": "fetch inside useEffect without abort",
"fix": "Add AbortController with cleanup"
},
{
"id": "RACE-002",
"severity": "medium",
"type": "unmount_update",
"title": "Possible State Update After Unmount",
"file": "src/hooks/useData.ts",
"line": 15,
"description": "Promise resolves after component unmounts",
"fix": "Add mounted flag or use React Query"
}
],
"recommendations": [
"Consider using React Query or SWR for data fetching",
"Add ESLint plugin for exhaustive deps",
"Use AbortController for cancellable requests"
]
}
}
Fast typing causes out-of-order responses. Fix: Debounce + AbortController
Server rejection after UI update. Fix: Rollback mechanism
Double-click causes duplicate submissions. Fix: Disable button + request deduplication
Page change before previous loads. Fix: Cancel previous request
Conflicting data sources. Fix: Single source of truth, reconciliation
You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.