dotnet/wpf · error · ArgumentException
SR.GetResourceString(srid)
Error message
SR.GetResourceString(srid)
What it means
In UpdateShaderConstant, after determining the register limits for the shader profile (e.g. PS_2_0 vs PS_3_0 constant register maxima, with the srid selecting the matching message such as Effect_Shader30BoolConstantRegisterLimit), a register index outside [0, registerMax) makes the effect throw ArgumentException with the corresponding resource string. The register referenced by PixelShaderConstantCallback does not exist in the shader profile.
Solutions
- Use a register index within the profile limit, or compile the shader with /T ps_3_0 to raise the limits.
- Reduce the number of constants (pack values into float4 registers, use arrays) to fit within the limit.
- Fix the register index passed to PixelShaderConstantCallback (must be >= 0 and < registerMax).
Example fix
// before new PropertyMetadata(0f, PixelShaderConstantCallback(45))); // ps_2_0 float limit exceeded // after new PropertyMetadata(0f, PixelShaderConstantCallback(12))); // within ps_2_0 limit
Defensive patterns
Strategy: validation
Validate before calling
// ps_2_0 float register limit is 32; check before registering the callback
if (registerIndex < 0 || registerIndex >= 32)
throw new ArgumentException("Constant register index out of range for the shader profile"); Try / catch
try
{
effect.ApplyAnimationClock(dp, null); // triggers UpdateShaderConstant path
}
catch (ArgumentException ex) when (ex.Message.Contains("register"))
{
// remap register index or recompile shader as ps_3_0
} Prevention
- Keep a central constant table mapping parameters to register indices and validate against profile limits.
- Pack scalar values into float4 registers to conserve ps_2_0 register space.
- Use ps_3_0 when you need more registers or int/bool constants.
When it happens
Trigger: Passing a register number >= the profile limit (e.g. register 32+ for float constants in ps_2_0, or bool/int registers with ps_2_0) or a negative register index to PixelShaderConstantCallback.
Common situations: Adding many shader parameters and running past the ps_2_0 constant register cap; reusing callback register numbers copied from ps_3_0 samples while the shader is compiled ps_2_0; typo in the register index (off-by-one or negative).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- SR.Effect_ShaderEffectPadding
- args
- args
- ArgumentOutOfRangeException(authenticationType)
- ArgumentOutOfRangeException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5a118a23d543d863.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Effects/ShaderEffect.cs:372
{
registerMax = PS_3_0_FLOAT_REGISTER_LIMIT;
srid = nameof(SR.Effect_Shader30FloatConstantRegisterLimit);
}
else if (t == typeof(int))
{
registerMax = PS_3_0_INT_REGISTER_LIMIT;
srid = nameof(SR.Effect_Shader30IntConstantRegisterLimit);
}
else if (t == typeof(bool))
{
registerMax = PS_3_0_BOOL_REGISTER_LIMIT;
srid = nameof(SR.Effect_Shader30BoolConstantRegisterLimit);
}
}
if (registerIndex >= registerMax || registerIndex < 0)
{
throw new ArgumentException(SR.GetResourceString(srid), nameof(dp));
}
if (t == typeof(float))
{
MilColorF fourTuple;
ConvertValueToMilColorF(newValue, out fourTuple);
StashInPosition(ref _floatRegisters, registerIndex, fourTuple, registerMax, ref _floatCount);
}
else if (t == typeof(int))
{
MilColorI fourTuple;
ConvertValueToMilColorI(newValue, out fourTuple);
StashInPosition(ref _intRegisters, registerIndex, fourTuple, registerMax, ref _intCount);
}
else if (t == typeof(bool))
{
StashInPosition(ref _boolRegisters, registerIndex, (bool)newValue, registerMax, ref _boolCount);
}View on GitHub (pinned to 81131a70a4)