dotnet/wpf · error · ArgumentException
SR.Effect_ShaderSamplerType
Error message
SR.Effect_ShaderSamplerType
What it means
UpdateShaderSampler validates that the value bound via PixelShaderSamplerCallback is a Brush the sampler pipeline supports: null, ImplicitInput, or specific supported brush types (e.g. not an arbitrary unsupported Brush such as a non-image/implicit brush type). If the property value is a Brush of an unsupported type (and not ImplicitInputBrush/ImageBrush-supported), ArgumentException with Effect_ShaderSamplerType is thrown.
Solutions
- Use ImageBrush with a valid BitmapImage/RenderTargetBitmap source for the sampler input.
- Use Effect.ImplicitInput for the element's own rendering, or null.
- Render the unsupported brush (e.g. VisualBrush) into a RenderTargetBitmap and assign that as an ImageBrush.
- Convert DrawingBrush/other brushes to bitmaps before applying the effect.
Example fix
// before samplerInput = new VisualBrush(targetVisual); // after var rtb = new RenderTargetBitmap((int)w, (int)h, 96, 96, PixelFormats.Pbgra32); rtb.Render(targetVisual); samplerInput = new ImageBrush(rtb);
Defensive patterns
Strategy: validation
Validate before calling
if (value is Brush b && b is not ImageBrush && value != Effect.ImplicitInput)
// unsupported sampler brush: convert to ImageBrush via RenderTargetBitmap before assigning Type guard
static bool IsSupportedSamplerValue(object v) =>
v == null || v == Effect.ImplicitInput || v is ImageBrush; Try / catch
try { effect.InputBrush = brush; }
catch (ArgumentException ex) when (ex.Message.Contains("sampler"))
{
effect.InputBrush = RenderBrushToImageBrush(brush); // RenderTargetBitmap fallback
} Prevention
- Only assign ImageBrush (or Effect.ImplicitInput / null) to sampler properties.
- Convert VisualBrush/DrawingBrush to RenderTargetBitmap-backed ImageBrush first.
- Avoid custom Brush subclasses as shader sampler inputs.
When it happens
Trigger: Assigning an unsupported Brush-derived type (e.g. VisualBrush, DrawingBrush, custom Brush) to a sampler-mapped dependency property that uses PixelShaderSamplerCallback.
Common situations: Using a VisualBrush to feed a shader sampler; passing a custom brush class; using a brush type not supported by the effect sampler pipeline in the target WPF version.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.BitmapCacheBrush_OpacityChanged
- SR.BitmapCacheBrush_RelativeTransformChanged
- SR.BitmapCacheBrush_TransformChanged
- SR.Effect_20ShaderUsing30Registers
- SR.Effect_ShaderConstantType
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/806a27d7432fbb94.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Effects/ShaderEffect.cs:423
// form that the HLSL shaders want, and stores that value, since it will
// be sent on every update.
// We WritePreamble/Postscript here since this method is called by the user with the callback
// created in PixelShaderSamplerCallback.
private void UpdateShaderSampler(DependencyProperty dp, object newValue, int registerIndex, SamplingMode samplingMode)
{
WritePreamble();
if (newValue != null)
{
if (newValue is not VisualBrush
and not BitmapCacheBrush
and not ImplicitInputBrush
and not ImageBrush)
{
// Note that if the type of the brush is ImplicitInputBrush and the value is non null, the value is actually
// Effect.ImplicitInput. This is because ImplicitInputBrush is internal and the user can only get to the singleton
// Effect.ImplicitInput.
throw new ArgumentException(SR.Effect_ShaderSamplerType, nameof(dp));
}
}
//
// Treat as ps_2_0 by default
//
int registerMax = PS_2_0_SAMPLER_LIMIT;
string srid = nameof(SR.Effect_Shader20SamplerRegisterLimit);
if (PixelShader != null && PixelShader.ShaderMajorVersion >= 3)
{
registerMax = PS_3_0_SAMPLER_LIMIT;
srid = nameof(SR.Effect_Shader30SamplerRegisterLimit);
}
if (registerIndex >= registerMax || registerIndex < 0)
{
throw new ArgumentException(SR.GetResourceString(srid));View on GitHub (pinned to 81131a70a4)