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

  1. Use ImageBrush with a valid BitmapImage/RenderTargetBitmap source for the sampler input.
  2. Use Effect.ImplicitInput for the element's own rendering, or null.
  3. Render the unsupported brush (e.g. VisualBrush) into a RenderTargetBitmap and assign that as an ImageBrush.
  4. 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

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


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)