Summary
useAskableTextSelectionCapture in packages/react/src/useAskableTextSelectionCapture.ts called currentOptions.onCapture?.(packet, selection) and currentOptions.onCancel?.() inside the capture handle callbacks. currentOptions is a snapshot captured at ensureHandle() call time.
In React, parent components re-render and pass new function references on each render. The optionsRef is updated each render to track the latest callbacks, but the handle callbacks used the stale closure instead. The result: if onCapture or onCancel changed between start() and the first capture event, the old callback was invoked.
The useAskableRegionCapture hook already handled this correctly using optionsRef.current.onCapture?.() — the text selection hook was inconsistent.
Impact
React components that inline the callback (common pattern) pass a new function instance on each render. If a selection is captured after a re-render, the previous render's callback fires instead of the current one. This can cause missed state updates or double-firing bugs.
Fix
Replace currentOptions.onCapture?.(...) and currentOptions.onCancel?.() with optionsRef.current.onCapture?.(...) and optionsRef.current.onCancel?.() to always call the latest callback.
Fixed in: claude/create-agents-md-fqfEf
Summary
useAskableTextSelectionCaptureinpackages/react/src/useAskableTextSelectionCapture.tscalledcurrentOptions.onCapture?.(packet, selection)andcurrentOptions.onCancel?.()inside the capture handle callbacks.currentOptionsis a snapshot captured atensureHandle()call time.In React, parent components re-render and pass new function references on each render. The
optionsRefis updated each render to track the latest callbacks, but the handle callbacks used the stale closure instead. The result: ifonCaptureoronCancelchanged betweenstart()and the first capture event, the old callback was invoked.The
useAskableRegionCapturehook already handled this correctly usingoptionsRef.current.onCapture?.()— the text selection hook was inconsistent.Impact
React components that inline the callback (common pattern) pass a new function instance on each render. If a selection is captured after a re-render, the previous render's callback fires instead of the current one. This can cause missed state updates or double-firing bugs.
Fix
Replace
currentOptions.onCapture?.(...)andcurrentOptions.onCancel?.()withoptionsRef.current.onCapture?.(...)andoptionsRef.current.onCancel?.()to always call the latest callback.Fixed in:
claude/create-agents-md-fqfEf