dotnet/wpf · error · InvalidOperationException

SR.Format(SR.ValidationRule_UnknownStep…

Error message

SR.Format(SR.ValidationRule_UnknownStep, validationRule.ValidationStep, validationRule)

What it means

During validation, the engine switches on the ValidationRule's ValidationStep to decide what value object to pass to the rule; the default branch throws this InvalidOperationException for any unrecognized step. Since ValidationStep is a closed enum this normally indicates an out-of-range or corrupted enum value rather than an app mistake.

Solutions

  1. Set ValidationRule.ValidationStep to a valid value: RawProposedValue, ConvertedProposedValue, UpdatedValue, or CommittedValue
  2. Check XAML/config for the rule's ValidationStep value and correct typos or out-of-range numbers
  3. Verify assembly/framework versions agree between the rule definition and the WPF runtime

Example fix

// before
rule.ValidationStep = (ValidationStep)99; // throws ValidationRule_UnknownStep
// after
rule.ValidationStep = ValidationStep.ConvertedProposedValue;
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(ValidationStep), rule.ValidationStep)) throw new InvalidOperationException("ValidationStep out of range");

Type guard

static bool IsKnownStep(ValidationStep s) => s is ValidationStep.RawProposedValue or ValidationStep.ConvertedProposedValue or ValidationStep.UpdatedValue or ValidationStep.CommittedValue;

Try / catch

try { RunValidation(rule); } catch (InvalidOperationException ex) when (ex.Message.Contains("ValidationStep")) { rule.ValidationStep = ValidationStep.ConvertedProposedValue; }

Prevention

When it happens

Trigger: A ValidationRule whose ValidationStep holds an invalid enum value (cast from int, deserialized from bad config/XAML producing a value outside the enum, or a newer enum value from a mismatched framework version hitting an older code path).

Common situations: Enum values deserialized from corrupted or hand-edited XAML/BAML; binary-formatted settings carrying an out-of-range ValidationStep; framework version mismatch where a rule was defined against a newer ValidationStep.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingExpression.cs:1562

                        {
                            case ValidationStep.RawProposedValue:
                                if (rawValue == DependencyProperty.UnsetValue)
                                {
                                    rawValue = GetRawProposedValue();
                                }
                                value = rawValue;
                                break;
                            case ValidationStep.ConvertedProposedValue:
                            case ValidationStep.UpdatedValue:
                            case ValidationStep.CommittedValue:
                                if (itemValue == DependencyProperty.UnsetValue)
                                {
                                    itemValue = Worker.RawValue();
                                }
                                value = itemValue;
                                break;
                            default:
                                throw new InvalidOperationException(SR.Format(SR.ValidationRule_UnknownStep, validationRule.ValidationStep, validationRule));
                        }

                        // lazy-fetch culture (avoids exception when target DP is Language)
                        if (culture == null)
                        {
                            culture = GetCulture();
                        }

                        validationError = RunValidationRule(validationRule, value, culture);
                        if (validationError != null)
                            break;
                    }
                }
            }

            if (needDataErrorRule && validationError == null)
            {
                // lazy-fetch culture (avoids exception when target DP is Language)

View on GitHub (pinned to 81131a70a4)