[BUG]: [iOS] Crash: Null check operator used on a null value in log callback when recording PCM16 stream
Flutter Sound Version :
-
FULL or LITE flavor ? FULL
-
Important: Result of the command :
flutter pub deps | grep flutter_sound├── flutter_sound 9.28.0 │ ├── flutter_sound_platform_interface 9.28.0 │ ├── flutter_sound_web 9.28.0 │ │ ├── flutter_sound_platform_interface...Note: This issue also occurs in taudio 10.3.8 (the successor package).
Severity
- Crash ? ✅ Yes - Crashes the VSCode debugging session when "All Exceptions" mode is enabled.
- Result is not what expected ? ✅ Yes
- Cannot build my App ? No
- Minor issue ? No
Platforms you faced the error
- iOS ? ✅ Yes
- Android ? No
- Flutter Web ? No
- Emulator ? Not tested
- Real device ? ✅ Yes
Describe the bug
When recording a PCM16 audio stream on iOS with VSCode's "All Exceptions" debugging mode enabled, a Null check operator used on a null value exception occurs, which immediately crashes the debugging session.
The root cause appears to be the iOS AVFoundation "hack" used for stream recording. This process creates a temporary AAC recorder to initialize the audio session. After the main Dart-side recorder instance is terminated and set to null, late-arriving log callbacks from the native side (related to the cleanup of this temporary recorder) attempt to call aRecorder!.log(), causing the null-check exception.
To Reproduce Steps to reproduce the behavior:
- In VSCode, go to the "Run and Debug" panel and enable the "All Exceptions" breakpoint.
- In your Flutter app, create and open a
FlutterSoundRecorderinstance. - Call
startRecorderwithCodec.pcm16and a validtoStreamsink to trigger the iOS-specific stream recording logic.FlutterSoundRecorder recorder = FlutterSoundRecorder(); await recorder.openRecorder(); // This specific combination triggers the bug on iOS await recorder.startRecorder( codec: Codec.pcm16, toStream: streamController.sink, ); - See error: The VSCode debugging session immediately halts and reports a
Null check operator used on a null valueexception atmethod_channel_flutter_sound_recorder.dart:163.
Logs!!!!
Standard flutter_sound logs (using logLevel: Level.debug) are not available for this specific issue.
The reason is that the exception occurs at a low level within the method channel handler. It is caught by the Dart VM debugger (due to "All Exceptions" mode) before Flutter's error handlers or the flutter_sound logger can process and display it. The immediate crash of the debug session prevents any further log capture.
The only available information is the stack trace provided by the debugger itself:
-
Exception:
Null check operator used on a null value -
Location:
flutter_sound_platform_interface/lib/method_channel_flutter_sound_recorder.dart:163 -
Failing code:
aRecorder!.log(l, call.arguments['msg']) -
Stack (simplified):
Future → Timer → Zone → _Timer → _handleMessage
Proposed Fix / Additional Context
To prevent this crash, a null check should be added in the method channel handler to safely ignore log callbacks from recorder sessions that have already been disposed of on the Dart side.
File: flutter_sound_platform_interface/lib/method_channel_flutter_sound_recorder.dart
Suggested Change:
case "log":
{
if (aRecorder != null) { // <-- ADD THIS CHECK
int i = call.arguments['level'];
Level l = Level.values.firstWhere((x) => x.value == i);
aRecorder.log(l, call.arguments['msg']);
} else {
// Safely ignore log callbacks from the cleaned-up iOS hack session.
// This prevents the "Null check operator used on a null value" exception.
}
}
break;
Yes @jill-chuang , I totally agree with your patch
Note: this hack is terrible. I have never understood why this hack was necessary on iOS. Perhaps a bug in iOS itself?
Thanks for the quick and positive reply! I agree, that iOS hack does seem tricky.
I'd be happy to create a Pull Request for this fix. However, I also understand if you prefer to apply the fix yourself since it's a small change.
Please just let me know which you'd prefer. Thanks!
That’s ok like that. I will write your patch myself. Please, expect some delay: actually I don’t have access to my computers.
Sounds great, thank you for handling it! No problem at all about the delay, please take your time. Thanks again for your work on this great package!