dotnet/wpf · error · InvalidOperationException

SR.CompatibilityPreferencesSealed…

Error message

SR.CompatibilityPreferencesSealed (FlowDispatcherSynchronizationContextPriority, BaseCompatibilityPreferences)

What it means

BaseCompatibilityPreferences.FlowDispatcherSynchronizationContextPriority is a startup-only knob: once WPF seals BaseCompatibilityPreferences (on first use of the WPF runtime), the setter throws InvalidOperationException with SR.CompatibilityPreferencesSealed naming this property. It exists so the framework can assume settings never change mid-flight.

Solutions

  1. Set the property before any Application/Dispatcher is created — as the first statements of Main or a module initializer.
  2. Document and centralize all BaseCompatibilityPreferences settings in one pre-init location.
  3. Guard with BaseCompatibilityPreferences-style checks or wrap in try-catch when the code may run after init, and skip the assignment.

Example fix

// before
public App()
{
    BaseCompatibilityPreferences.FlowDispatcherSynchronizationContextPriority = false;
    InitializeComponent();
}
// after
// in Main(), before constructing App:
BaseCompatibilityPreferences.FlowDispatcherSynchronizationContextPriority = false;
Defensive patterns

Strategy: validation

Validate before calling

// Pre-init config step:
void ApplyCompatPreferences()
{
    BaseCompatibilityPreferences.FlowDispatcherSynchronizationContextPriority = shouldFlow;
}

Try / catch

try { BaseCompatibilityPreferences.FlowDispatcherSynchronizationContextPriority = v; }
catch (InvalidOperationException) { log.LogWarning("Preferences already sealed; value not applied"); }

Prevention

When it happens

Trigger: Setting BaseCompatibilityPreferences.FlowDispatcherSynchronizationContextPriority after Dispatcher/Application initialization, e.g. in App startup handlers, window constructors, or code triggered by the first DispatcherFrame.

Common situations: Conditional compatibility tweaks added after the app grew past single-threaded startup; library code trying to flip the flag on behalf of the host app; test fixtures sharing a process where WPF is already initialized.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/BaseCompatibilityPreferences.cs:135

        ///     .Net 4.5, we now record the priority of the DispatcherOperation
        ///     in the DispatcherSynchronizationContext and use that to satisfy
        ///     SynchronizationContext.Post and SynchronizationContext.Send
        ///     calls.  This enables async operations to "resume" after an
        ///     await statement at the same priority they are currently running
        ///     at.
        ///
        ///     This is, of course, an observable change in behavior.
        /// </summary>
        public static bool FlowDispatcherSynchronizationContextPriority
        {
            get { return _flowDispatcherSynchronizationContextPriority; }
            set
            {
                lock (_lockObject)
                {
                    if (_isSealed)
                    {
                        throw new InvalidOperationException(SR.Format(SR.CompatibilityPreferencesSealed, "FlowDispatcherSynchronizationContextPriority", "BaseCompatibilityPreferences"));
                    }

                    _flowDispatcherSynchronizationContextPriority = value;
                }
            }
        }

        internal static bool GetFlowDispatcherSynchronizationContextPriority()
        {
            Seal();

            return FlowDispatcherSynchronizationContextPriority;
        }

#if NETFX && !NETCOREAPP
        private static bool _flowDispatcherSynchronizationContextPriority = BinaryCompatibility.TargetsAtLeast_Desktop_V4_5 ? true : false;
#elif NETCOREAPP
        private static bool _flowDispatcherSynchronizationContextPriority = true;

View on GitHub (pinned to 81131a70a4)