Skip to content

🐛 [iOS 26] SIGABRT on camera teardown — AVCaptureSession dealloc → detachFromFigCaptureSession assert (V5 detach-side of #3730/#3773) #4026

Description

@duc-beluga

What's happening?

On iOS 26, the app crashes with EXC_CRASH (SIGABRT) when the <Camera> view is torn down (unmounting the screen after capturing a photo). The crash is an AVFoundation assertion fired from -[AVCaptureSession dealloc] running on the main thread inside a CA::Transaction::commit() — the AVCaptureVideoPreviewLayer's deferred release cascades into a session dealloc that asserts in detachFromFigCaptureSession.

This is the detach/teardown side of the race in #3773 (attach side, open). #3730 was the detach side too and was closed as "fixed in V5" — this reproduces on V5 (5.0.10), so the teardown side does not appear fixed. Setting isActive={false} before unmount and delaying the unmount ~240ms both reduce but do not eliminate it.

Reproduceable Code

<Camera> is mounted inside a bottom-sheet/overlay. After capturePhotoToFile resolves, the photo-preview branch renders (so <Camera> unmounts), then the overlay itself unmounts on submit.

const device = useCameraDevice('back');
const photoOutput = usePhotoOutput({ qualityPrioritization: 'speed', containerFormat: 'jpeg' });

<Camera
  style={StyleSheet.absoluteFill}
  device={device}
  outputs={[photoOutput]}     // photo only
  isActive={appForeground && hostOpen}
  onError={...}
/>

Relevant log output

Symbolicated, byte-for-byte identical across 2 TestFlight crash reports:

2   libsystem_c.dylib   abort
3   libsystem_c.dylib   __assert_rtn
4   AVFCapture  -[AVCaptureOutput detachFromFigCaptureSession:]_block_invoke.cold.1 (AVCaptureOutput.m:329)
5   AVFCapture  -[AVCaptureOutput detachFromFigCaptureSession:]_block_invoke (AVCaptureOutput.m:329)
8   AVFCapture  -[AVCaptureOutput detachFromFigCaptureSession:] (AVCaptureOutput.m:325)
9   CoreFoundation  -[NSSet makeObjectsPerformSelector:withObject:]
10  AVFCapture  -[AVCaptureSession _makeConfigurationLive:] (AVCaptureSession.m:4862)
11  AVFCapture  -[AVCaptureSession dealloc] (AVCaptureSession.m:596)
12  AVFCapture  -[AVCaptureVideoPreviewLayer dealloc] (AVCaptureVideoPreviewLayer.m:440)
13  Foundation  _NSKVOPerformWithDeallocatingObservable
14  Foundation  NSKVODeallocate
15  QuartzCore  CA::release_objects(X::List<void const*>*)
16  QuartzCore  CA::Transaction::commit()
17  QuartzCore  CA::Transaction::flush_as_runloop_observer(bool)
18  UIKitCore   _UIApplicationFlushCATransaction

Camera Device

useCameraDevice('back') — the logical multi-cam virtual device.

Device

iPhone 13 Pro Max (iPhone14,3) — multi-physical-camera. #3773 notes the race widens on multi-cam devices (slower CoreMedia XPC commit propagation); consistent here.

VisionCamera Version

5.0.10 · React Native 0.83 · Expo SDK 55 · New Architecture / Nitro · iOS 26.5

Can you reproduce this issue in the VisionCamera Example app?

Not yet tried — happy to attempt a minimal repro if it would help.

Additional information

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions