[video_player] `_playerWith` throws unrecoverable StateError when native player is destroyed by OS during CONFIGURATION_CHANGED / LOW_MEMORY
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
Research direction
Start with buildViewWithOptions in android_video_player.dart and avfoundation_video_player.dart, alongside the _playerWith implementations and the reported _VideoPlayerState.build call path. Verify the missing-player case during rebuilds after disposal or configuration changes. Done means both platforms return an empty widget instead of throwing when the player ID is absent.
Written by the indexing model from the issue text.
Description
Steps to reproduce
- Open a video player in fullscreen (landscape)
- Background the app (lock screen / home button)
- Wait for Android to trigger LOW_MEMORY (~40%) or iOS to reclaim AVPlayer resources
- Return to app → CONFIGURATION_CHANGED fires (orientation change)
_VideoPlayerState.build()→buildViewWithOptions(playerId)→_playerWith(id)throwsStateError
Expected results
buildViewWithOptions should handle missing players gracefully (return empty widget) instead of throwing.
Actual results
StateError: Bad state: No active player with ID 4.
iOS stack trace:
avfoundation_video_player.dart:327 in AVFoundationVideoPlayer._playerWith
avfoundation_video_player.dart:304 in AVFoundationVideoPlayer.buildViewWithOptions
video_player.dart:1143 in _VideoPlayerState.build
Android stack trace:
android_video_player.dart:298 in AndroidVideoPlayer._playerWith
Impact
- 3,400+ events (2.2K iOS + 1.2K Android) from ~500 users in 30 days
- Devices under memory pressure: OPPO Reno3 (MediaTek), Samsung A13, iPad Air 5th gen
- Level:
Error— app doesn't crash but video widget becomes unrecoverable
Root Cause
_playerWith throws when player ID is not in _players map:
// android_video_player.dart:296-298 / avfoundation_video_player.dart:325-327
_PlayerInstance _playerWith({required int id}) {
final _PlayerInstance? player = _players[id];
return player ?? (throw StateError('No active player with ID $id.'));
}
The race: dispose() removes from _players, but the VideoPlayer widget is still mounted (AnimatedSwitcher transition / rebuild during CONFIGURATION_CHANGED). build() calls buildViewWithOptions → throws.
Proposed Fix
Guard buildViewWithOptions to return empty widget when player is gone:
android_video_player.dart:
@override
Widget buildViewWithOptions(VideoViewOptions options) {
final int playerId = options.playerId;
final _PlayerInstance? player = _players[playerId];
if (player == null) return const SizedBox.shrink();
return _buildExoPlayerView(playerId);
}
avfoundation_video_player.dart:
@override
Widget buildViewWithOptions(VideoViewOptions options) {
final int playerId = options.playerId;
final _PlayerInstance? player = _players[playerId];
if (player == null) return const SizedBox.shrink();
final VideoPlayerViewState viewState = player.viewState;
return switch (viewState) {
VideoPlayerTextureViewState(:final int textureId) => Texture(textureId: textureId),
VideoPlayerPlatformViewState() => _buildPlatformView(playerId),
};
}
Environment
Flutter 3.44.0-3.44.6 (stable), Dart 3.12.0-3.12.2
video_player: 2.13.0, video_player_android: 2.11.0, video_player_avfoundation: 2.11.0
Tested on: OPPO Reno3 (Android 12, MediaTek MT6779), iPad Air 5th gen (iOS 26.6), iPhone 13 (iOS 26.5.2)
- Dominant language
- Dart
- Stars
- 179k
- Forks
- 31.7k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 413
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from flutter/flutter
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
c: tech-debt package team-ecosystem
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
waiting for response
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
-
waiting for response
Difficulty 1/5 Under an hour Newbie friendliness 88/100
-
material_ui 1.3.0 & cupertino_ui 1.1.0 on Flutter 3.44 Error: Undefined name 'awaitNotRequired'. Openp: cupertino_ui p: material_ui package team-design
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
code quality good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Suwayomi/Suwayomi-Tsumiru#479 ·
-
Build Failure: agora_rtc_engine compiled against android-31 while dependencies require android-34+ Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
conceptadev/noir#95 ·