dotnet/wpf · error · InvalidOperationException

SR.MediaContext_NoBadShaderHandler

Error message

SR.MediaContext_NoBadShaderHandler

What it means

MediaContext.NotifyBadPixelShader throws InvalidOperationException(SR.MediaContext_NoBadPixelShaderHandler) when the render thread reports an invalid/crashed pixel shader but no Application-specific bad-shade handler (MediaContext.RenderCapability... / EffectsLayer invalidation handler) is hooked. WPF requires an event handler to decide what to do when a shader effect is invalid.

Solutions

  1. Hook the bad-shader notification handler (System.Windows.Media.RenderCapability tier check / HardwareAcceleration) or ensure Effects are valid PS 2.0/3.0.
  2. Remove or replace the offending ShaderEffect with a software-renderable effect.
  3. Validate the compiled .ps bytecode (instruction count, texture reads) against the target shader profile.
  4. Disable hardware acceleration fallback path by testing with Tier 0 rendering to catch shader problems early.

Example fix

// before
// No handler; shader crash -> InvalidOperationException
myEffect = new MyCustomShaderEffect();
// after
// Validate tier / fall back to software effect if shader unsupported
if (RenderCapability.Tier >> 16 < 2)
    myEffect = new BlurEffect(); // safe software fallback
else
    myEffect = new MyCustomShaderEffect();
Defensive patterns

Strategy: try-catch

Validate before calling

// Prefer software-safe effects when hardware tier is low:
bool hwOk = RenderCapability.Tier >> 16 >= 2;
if (!hwOk) effect = softwareFallbackEffect;

Try / catch

try { ApplyShaderEffect(element); }
catch (InvalidOperationException ex) when (ex.Message.Contains("shader")) { element.Effect = new BlurEffect(); /* software fallback */ }

Prevention

When it happens

Trigger: Using a BitmapEffect / custom pixel shader (ShaderEffect) that fails validation or crashes on the render thread, while no bad-shader handler is registered, and MediaContext notifies the failure.

Common situations: Custom HLSL PS 2.0/3.0 shaders with invalid instruction counts, shaders compiled for unsupported instruction sets, or hardware that fails to run the effect; apps that shipped effects without handling shader failure events.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MediaContext.cs:403

        /// <summary>
        /// NotifyBadPixelShader - this method is called when the render
        /// thread has detected a bad pixel shader.  The render thread continues
        /// to raise this until the problem's been corrected.  This method
        /// invokes the listeners on the static event in PixelShader.
        /// </summary>
        private void NotifyBadPixelShader()
        {
            if (InvalidPixelShaderEncountered != null)
            {
                InvalidPixelShaderEncountered(null, null);
            }
            else
            {
                // It's never correct to not have an event handler hooked up in
                // the case when an invalid shader is encountered.  Raise an
                // exception directing the app to hook up an event handler.
                throw new InvalidOperationException(SR.MediaContext_NoBadShaderHandler);
            }
        }

        /// <summary>
        /// The partition this media context is connected to went into
        /// zombie state. This means either an unhandled batch processing,
        /// rendering or presentation error and will require us to reconnect.
        /// </summary>
        private void NotifyPartitionIsZombie(int failureCode)
        {
            //
            // We only get back these kinds of notification:-
            // For all OOM cases, we get E_OUTOFMEMORY.
            // For all OOVM cases, we get D3DERR_OUTOFVIDEOMEMORY and
            // for all other errors we get WGXERR_UCE_RENDERTHREADFAILURE.
            //

            switch (failureCode)

View on GitHub (pinned to 81131a70a4)