From 6244988d79a80868781af4750c78df2efbd2a532 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 1 Dec 2025 13:15:23 +0000 Subject: [PATCH] fix: prevent crash from accessing released AudioRecorder ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - use recorderState.isRecording instead of recorderRef.current.isRecording - avoid touching native shared object after it's been released - fixes production crash: 'cannot cast to AudioRecorder (received Integer)' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- packages/app/src/hooks/use-audio-recorder.native.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/app/src/hooks/use-audio-recorder.native.ts b/packages/app/src/hooks/use-audio-recorder.native.ts index 275d34724..c93f6f617 100644 --- a/packages/app/src/hooks/use-audio-recorder.native.ts +++ b/packages/app/src/hooks/use-audio-recorder.native.ts @@ -178,7 +178,7 @@ export function useAudioRecorder(config?: AudioCaptureConfig) { // Use configRef to access the latest callback without recreating the effect useEffect(() => { const currentConfig = configRef.current; - if (!currentConfig?.onAudioLevel || !recorderRef.current.isRecording) return; + if (!currentConfig?.onAudioLevel || !recorderState.isRecording) return; const interval = setInterval(() => { const metering = recorderState.metering; @@ -346,8 +346,8 @@ export function useAudioRecorder(config?: AudioCaptureConfig) { const isRecording = useCallback(() => { // Treat local intent as backup so callers can detect pending sessions - return recorderRef.current.isRecording || recordingIntentRef.current; - }, []); + return Boolean(recorderState.isRecording) || recordingIntentRef.current; + }, [recorderState.isRecording]); // Return stable object using useMemo return useMemo(() => ({