LiveKit Rust SDK Crash On MacOS 26: NSInvalidArgumentException
Encountering crashes in your applications can be a frustrating experience, especially when the error messages are cryptic. This article delves into a specific crash, the NSInvalidArgumentException, occurring in the LiveKit Rust SDK on macOS 26 (Tahoe). We'll break down the error, its root cause, and potential solutions.
Understanding the NSInvalidArgumentException
At the heart of the issue is an NSInvalidArgumentException, specifically triggered by an unrecognized selector sent to a class. In simpler terms, the application is trying to call a method (stringForAbslStringView:) that doesn't exist within the NSString class as defined in macOS 26. The verbose crash log paints a clearer picture:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSString stringForAbslStringView:]: unrecognized selector sent to class 0x1efa163d8'
*** First throw call stack:
(
0 CoreFoundation 0x000000018314d8dc __exceptionPreprocess + 176
1 libobjc.A.dylib 0x0000000182c26418 objc_exception_throw + 88
2 CoreFoundation 0x000000018322dc68 -[NSObject(NSObject) doesNotRecognizeSelector:] + 0
3 CoreFoundation 0x00000001830eaef8 ___forwarding___ + 1480
4 CoreFoundation 0x00000001830ea870 _CF_forwarding_prep_0 + 96
5 phono 0x000000010175f290 +[RTCVideoEncoderVP9 scalabilityModes] + 168
6 phono 0x00000001017689f4 +[RTCDefaultVideoEncoderFactory supportedCodecs] + 484
7 phono 0x0000000101768d80 -[RTCDefaultVideoEncoderFactory supportedCodecs] + 44
8 phono 0x0000000101768ff8 -[RTCVideoEncoderFactorySimulcast supportedCodecs] + 72
9 phono 0x000000010175c5f0 _ZNK6webrtc23ObjCVideoEncoderFactory19GetSupportedFormatsEv + 88
10 phono 0x00000001019c4388 _ZNK7livekit19VideoEncoderFactory15InternalFactory19GetSupportedFormatsEv + 184
...
)
libc++abi: terminating due to uncaught exception of type NSException
This error typically arises when there's a mismatch between the code's expectations and the actual API available in the operating system. In this specific scenario, the LiveKit Rust SDK, while utilizing prebuilt WebRTC binaries, encounters an issue during the initialization of the video encoder factory.
The Culprit: WebRTC and macOS 26 API Incompatibility
Delving deeper, the root cause lies in the prebuilt WebRTC binaries within the webrtc-sys crate. These binaries contain an NSString category method, stringForAbslStringView:, which is absent in macOS 26's Foundation framework. This API incompatibility between the WebRTC binaries and the newer macOS SDK triggers the crash.
Specifically, the crash occurs during the WebRTC PeerConnectionFactory initialization process. This factory attempts to determine supported video codecs, which leads to the invocation of the problematic stringForAbslStringView: method. The prebuilt WebRTC binaries in webrtc-sys use an NSString category method stringForAbslStringView: that doesn't exist in macOS 26's Foundation framework. This indicates an API compatibility issue with the newer macOS SDK.
Environment Details
To provide context, the crash occurs under the following conditions:
- Operating System: macOS 26.1 (Build 25B5072a)
- Architecture: arm64 (Apple Silicon)
- LiveKit: 0.7.25
- libwebrtc: 0.3.20
- webrtc-sys: 0.3.17
Steps to Reproduce
The crash can be consistently reproduced by following these steps:
- Create a straightforward program that establishes a connection to a LiveKit room on macOS 26.
- Execute the program on an Apple Silicon Mac running macOS 26 (Tahoe).
A minimal code snippet to trigger the issue might resemble:
use livekit::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (room, _) = Room::connect(
"wss://your-livekit-server",
"token",
RoomOptions::default(),
).await?;
println!("Connected to room: {:?}", room);
Ok(())
}
The Implications: Audio-Only Use Case
Interestingly, this issue surfaces even in audio-only scenarios, such as SIP telephony applications. This is because the video encoder initialization takes place during the PeerConnectionFactory setup, regardless of whether video functionality is actively used. While the application might be intended for audio only, the underlying WebRTC initialization process still attempts to set up video capabilities, leading to the crash.
Potential Solutions and Workarounds
Several avenues can be explored to address this issue:
- Updating WebRTC Binaries: The most direct approach is to update the prebuilt WebRTC binaries within
webrtc-systo a version compatible with macOS 26. This might involve building WebRTC from source with the macOS 26 SDK or utilizing prebuilt binaries specifically targeting this version. - Conditional Code Execution: Implement conditional code execution based on the operating system version. This would entail using different code paths for macOS 26 and older versions, potentially avoiding the problematic
stringForAbslStringView:call on the newer OS. - Disabling Video Codec Initialization (Workaround): A temporary workaround, particularly for audio-only applications, could be to introduce an option to disable video codec initialization. This would prevent the crash but might limit functionality if video support is required in the future.
Proposed Solutions in Detail
Updating WebRTC Binaries
This approach tackles the root cause of the problem by ensuring compatibility between the WebRTC binaries and the target macOS version. It involves the following steps:
- Obtain Compatible Binaries: Acquire WebRTC binaries built specifically for macOS 26. This might involve:
- Building WebRTC from source using the macOS 26 SDK.
- Sourcing prebuilt binaries from a trusted provider that explicitly supports macOS 26.
- Integrate into
webrtc-sys: Replace the existing WebRTC binaries within thewebrtc-syscrate with the newly obtained compatible binaries. This typically involves modifying the build process ofwebrtc-systo point to the new binaries. - Test Thoroughly: After integration, conduct rigorous testing on macOS 26 to ensure that the crash is resolved and that all WebRTC functionalities operate as expected.
Conditional Code Execution
This approach introduces OS-specific code paths to avoid the problematic API call on macOS 26. The steps involved are:
- Detect OS Version: Implement a mechanism to detect the operating system version at runtime. This can be achieved using system APIs or platform-specific crates in Rust.
- Conditional Logic: Introduce conditional logic in the code that initializes the video encoder factory. On macOS 26, a different initialization path would be taken, avoiding the call to
stringForAbslStringView:. This might involve using alternative APIs or deferring video encoder initialization. - Maintain Functionality: Ensure that the alternative code path maintains the required functionality, even without using the problematic API call. This might involve using different methods to enumerate supported codecs or configure the video encoder factory.
Disabling Video Codec Initialization (Workaround)
This workaround provides a temporary solution for audio-only applications by preventing the crash-inducing code from being executed. The steps involved are:
- Introduce Configuration Option: Add a configuration option to the LiveKit Rust SDK that allows users to disable video codec initialization.
- Conditional Initialization: Modify the
PeerConnectionFactoryinitialization code to check this configuration option. If video codec initialization is disabled, skip the code section that triggers thestringForAbslStringView:call. - Document Limitation: Clearly document that this workaround limits the application to audio-only functionality and that video capabilities will be unavailable when this option is enabled.
Conclusion
The NSInvalidArgumentException crash in the LiveKit Rust SDK on macOS 26 highlights the importance of API compatibility when working with prebuilt binaries and evolving operating systems. By understanding the root cause and exploring the potential solutions outlined above, developers can mitigate this issue and ensure the smooth operation of their applications on the latest macOS versions. Addressing this incompatibility will not only resolve the crash but also contribute to the overall stability and reliability of the LiveKit Rust SDK.
For more in-depth information on WebRTC and its compatibility with different platforms, visit the official WebRTC website. This resource offers valuable insights into the technology and its evolving landscape.