dotnet/wpf · error · NotSupportedException

SR.Image_BadVersion

Error message

SR.Image_BadVersion

What it means

MediaPlayerState.VerifyAPI ensures calls are made on the UI thread AND that the underlying native media object (_nativeMedia) still exists and is valid. If the native media handle is null or has been released (IsInvalid), any state query such as IsBuffering, CanPause, DownloadProgress, BufferingProgress, NaturalVideoHeight, or NaturalVideoWidth throws NotSupportedException (message resource SR.Image_BadVersion).

Solutions

  1. Guard state queries: only read properties after MediaOpened and before Close/teardown
  2. Handle NullReference/NotSupported by checking player.Source and MediaElement state (e.g. mediaElement.Source != null && mediaLoaded) first
  3. Subscribe to MediaClosed/Unloaded and stop polling timers that read these properties
  4. Reopen the media if you need the state after it was closed

Example fix

// before
double h = player.NaturalVideoHeight; // throws if native media gone
// after
if (player != null && player.HasVideo && player.Source != null)
{
    double h = player.NaturalVideoHeight;
}
Defensive patterns

Strategy: validation

Validate before calling

bool CanQueryState(MediaElement me) => me != null && me.Source != null && me.Clock == null && (me.CurrentState == MediaState.Play || me.CurrentState == MediaState.Pause || me.CurrentState == MediaState.Stop);

Type guard

bool HasValidNativeMedia(MediaPlayer p) => p != null && p.Source != null && !p.IsDisposed;

Try / catch

try { var h = player.NaturalVideoHeight; } catch (NotSupportedException) { h = 0; /* native media unavailable */ }

Prevention

When it happens

Trigger: Querying any MediaPlayerState property (IsBuffering, CanPause, DownloadProgress, BufferingProgress, NaturalVideoHeight, NaturalVideoWidth) after the native media player has been closed, disposed, or before a media source was successfully opened.

Common situations: Reading NaturalVideoWidth/NaturalVideoHeight before MediaOpened fires, polling DownloadProgress after Close() or unloading the MediaElement, or accessing state from event handlers after the player was torn down.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/df0e9ef86230ac76. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MediaPlayerState.cs:985

        /// are being called from the correct thread. This method should
        /// be the first thing called from any internal method.
        /// </summary>
        private void VerifyAPI()
        {
            //
            // We create _nativeMedia in the constructor, so it should always
            // be initialized.
            //
            Debug.Assert(_nativeMedia != null && !_nativeMedia.IsInvalid);

            //
            // We only allow calls to any media object on the UI thread.
            //
            _dispatcher.VerifyAccess();

            if (_nativeMedia == null || _nativeMedia.IsInvalid)
            {
                throw new System.NotSupportedException(SR.Image_BadVersion);
            }
        }

        /// <summary>
        /// Verifies that this player is not currently controlled by a clock. Some actions are
        /// invalid while we are under clock control.
        /// </summary>
        private
        void
        VerifyNotControlledByClock()
        {
            if (Clock != null)
            {
                throw new InvalidOperationException(SR.Media_NotAllowedWhileTimingEngineInControl);
            }
        }

        /// <summary>

View on GitHub (pinned to 81131a70a4)