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
- Hook the bad-shader notification handler (System.Windows.Media.RenderCapability tier check / HardwareAcceleration) or ensure Effects are valid PS 2.0/3.0.
- Remove or replace the offending ShaderEffect with a software-renderable effect.
- Validate the compiled .ps bytecode (instruction count, texture reads) against the target shader profile.
- 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
- Validate custom .ps shaders (profile, instruction count) in CI before shipping
- Hook bad-shader handling rather than relying on defaults
- Test effects on Tier 1/0 hardware and in remote sessions
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
- D3DERR_OUTOFVIDEOMEMORY
- E_OUTOFMEMORY
- E_UNEXPECTED
- SR.Freezable_UnregisteredHandler
- WGXERR_UCE_RENDERTHREADFAILURE
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)