What's happening?
On iOS 26.4.2, calling photoOutput.capturePhoto(...) from JS reliably aborts the app with EXC_BREAKPOINT (SIGTRAP) brk 1 — a Swift runtime trap — inside HybridCameraPhotoOutput.capturePhoto(settings:callbacks:) at HybridCameraPhotoOutput.swift:167:
// 3. Perform capture
output.capturePhoto(with: captureSettings, delegate: delegate)
The do { try settings.toAVCapturePhotoSettings(...) ... } catch { ... } block on lines 162–172 doesn't catch it — the trap is Swift's brk 1 (try! / precondition / force-unwrap / fatalError), not a Swift Error. The settings construction on line 164 succeeded (no catch path entered); the trap fires on the next instruction.
+1104 byte offset from the function start, source-line attribution = HybridCameraPhotoOutput.swift:167.
Stack ends in RCTJSThreadManager runRunLoop — i.e., the JS thread is the one driving the call (HybridFunction::callMethod → HybridCameraPhotoOutputSpecSwift::capturePhoto → Swift). Photo capture is initiated from JS via the public photoOutput.capturePhoto(...) API; no out-of-band thread is involved.
The app cannot wrap this in try/catch (JS) or do/catch (Swift) — by the time control could return, the process is already terminated by the kernel.
Suspect
Lines 65–70 of the same file are the only iOS-26-conditional block in the photo-output path:
if #available(iOS 26, *),
output.isCameraSensorOrientationCompensationSupported
{
output.isCameraSensorOrientationCompensationEnabled = false
}
This runs in init before any capture. It is the only iOS-26-specific configuration applied to the AVCapturePhotoOutput. Possible interaction with the settings produced by toAVCapturePhotoSettings on iOS 26 — worth ruling in/out.
Reproduceable Code
Camera configured with usePhotoOutput and useVideoOutput, both wired into <Camera outputs={outputs} />:
const PHOTO_OUTPUT_OPTIONS = {
targetResolution: CommonResolutions.UHD_4_3,
qualityPrioritization: 'quality',
quality: 0.95,
} as const;
const photoOutput = usePhotoOutput(PHOTO_OUTPUT_OPTIONS);
// On photo-mode mount, pre-warm flash variants (documented perf pattern):
useEffect(() => {
if (mode !== 'photo') return;
photoOutput
.prepareSettings([
{ flashMode: 'off', enableShutterSound: false },
{ flashMode: 'on', enableShutterSound: false },
{ flashMode: 'auto', enableShutterSound: false },
])
.catch(err => /* log */);
}, [mode, photoOutput]);
// Shutter tap:
const photo = await photoOutput.capturePhoto(
{
flashMode: 'off', // or 'on' / 'auto'
enableShutterSound: false,
location: captureLocation, // optional { latitude, longitude, ... }
},
{},
);
Vanilla usage — no custom settings beyond what's documented.
Relevant log output
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000105c4b028
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Triggered by Thread: 4 (RCTJSThreadManager — JS thread)
Thread 4 Crashed:
0 App HybridCameraPhotoOutput.capturePhoto(settings:callbacks:) + 1104 (HybridCameraPhotoOutput.swift:167)
1 App protocol witness for HybridCameraPhotoOutputSpec_protocol.capturePhoto(settings:callbacks:) in conformance HybridCameraPhotoOutput + 20
2 App HybridCameraPhotoOutputSpec_cxx.capturePhoto(settings:callbacks:) + 88 (HybridCameraPhotoOutputSpec_cxx.swift:145)
3 App margelo::nitro::camera::HybridCameraPhotoOutputSpecSwift::capturePhoto(...) + 64 (HybridCameraPhotoOutputSpecSwift.hpp:104)
4 App facebook::jsi::Value margelo::nitro::HybridFunction::callMethod<...> + 176 (HybridFunction.hpp:179)
5 App margelo::nitro::HybridFunction::createHybridFunction<...> + 280 (HybridFunction.hpp:119)
6-10 hermesvm HermesRuntimeImpl::HFContext::func → NativeFunction::_nativeCall → Interpreter::handleCallSlowPath → interpretFunction
11-13 hermesvm JSFunction::_callImpl → Callable::executeCall2 → generatorPrototypeResume
14-19 hermesvm …interpretFunction → JSFunction::_callImpl → Callable::executeCall3 → arrayPrototypeForEach
20+ hermesvm …interpretFunction → HermesRuntimeImpl::call
+ App facebook::react::UIManagerBinding::dispatchEventToJS
+ App facebook::react::Scheduler → EventQueueProcessor::flushEvents → RuntimeScheduler_Modern::runEventLoop
+ App RCTMessageThread::runAsync → __CFRunLoopDoBlocks → CFRunLoopRunSpecific
+ App +[RCTJSThreadManager runRunLoop] + 204 (RCTJSThreadManager.mm:102)
Thread State at trap:
pc: 0x0000000105c4b028 (== `HybridCameraPhotoOutput.capturePhoto + 1104`)
esr: 0xf2000001 (Breakpoint) brk 1
The brk 1 ESR confirms this is the Swift runtime trap instruction, not a memory fault.
Camera Device
Back camera, no special configuration beyond targetResolution: UHD_4_3 + qualityPrioritization: 'quality'. Format auto-selected by RNVC. HDR off at time of capture.
Device
iPad 10th gen (iPad13,18), iOS 26.4.2 (23E261).
A related but distinct crash signature in the same HybridCameraPhotoOutput / CapturePhotoDelegate module also reproduces on iPhone 11 Pro (iPhone12,1) / iOS 18.7.8 (22H352) — different stack (delegate callback during _handlePreparationCompleteNotificationWithPayload while a session start is in flight on another thread). Filed separately as #3917.
VisionCamera Version
5.0.10
Can you reproduce this issue in the VisionCamera Example app?
Not yet tested against the bare example app — the user-side trigger is a normal shutter tap in our app's photo-capture screen, which has reproduced on a TestFlight build (iOS 26.4.2 / iPad 10), but I don't have a repro count from a single device session. Happy to attempt a minimal repro in the example app if the suspect lines (65–70) don't immediately point you somewhere.
Additional information
What's happening?
On iOS 26.4.2, calling
photoOutput.capturePhoto(...)from JS reliably aborts the app withEXC_BREAKPOINT (SIGTRAP) brk 1— a Swift runtime trap — insideHybridCameraPhotoOutput.capturePhoto(settings:callbacks:)atHybridCameraPhotoOutput.swift:167:The
do { try settings.toAVCapturePhotoSettings(...) ... } catch { ... }block on lines 162–172 doesn't catch it — the trap is Swift'sbrk 1(try!/precondition/ force-unwrap /fatalError), not a SwiftError. The settings construction on line 164 succeeded (no catch path entered); the trap fires on the next instruction.+1104byte offset from the function start, source-line attribution =HybridCameraPhotoOutput.swift:167.Stack ends in
RCTJSThreadManager runRunLoop— i.e., the JS thread is the one driving the call (HybridFunction::callMethod→HybridCameraPhotoOutputSpecSwift::capturePhoto→ Swift). Photo capture is initiated from JS via the publicphotoOutput.capturePhoto(...)API; no out-of-band thread is involved.The app cannot wrap this in
try/catch(JS) ordo/catch(Swift) — by the time control could return, the process is already terminated by the kernel.Suspect
Lines 65–70 of the same file are the only iOS-26-conditional block in the photo-output path:
This runs in
initbefore any capture. It is the only iOS-26-specific configuration applied to theAVCapturePhotoOutput. Possible interaction with the settings produced bytoAVCapturePhotoSettingson iOS 26 — worth ruling in/out.Reproduceable Code
Camera configured with
usePhotoOutputanduseVideoOutput, both wired into<Camera outputs={outputs} />:Vanilla usage — no custom settings beyond what's documented.
Relevant log output
Thread State at trap:
The
brk 1ESR confirms this is the Swift runtime trap instruction, not a memory fault.Camera Device
Back camera, no special configuration beyond
targetResolution: UHD_4_3+qualityPrioritization: 'quality'. Format auto-selected by RNVC. HDR off at time of capture.Device
iPad 10th gen (
iPad13,18), iOS 26.4.2 (23E261).A related but distinct crash signature in the same
HybridCameraPhotoOutput/CapturePhotoDelegatemodule also reproduces on iPhone 11 Pro (iPhone12,1) / iOS 18.7.8 (22H352) — different stack (delegate callback during_handlePreparationCompleteNotificationWithPayloadwhile a session start is in flight on another thread). Filed separately as #3917.VisionCamera Version
5.0.10
Can you reproduce this issue in the VisionCamera Example app?
Not yet tested against the bare example app — the user-side trigger is a normal shutter tap in our app's photo-capture screen, which has reproduced on a TestFlight build (iOS 26.4.2 / iPad 10), but I don't have a repro count from a single device session. Happy to attempt a minimal repro in the example app if the suspect lines (65–70) don't immediately point you somewhere.
Additional information