dotnet/wpf · error · InvalidOperationException

SR.Format(SR.CompatibilityPreferencesSealed…

Error message

SR.Format(SR.CompatibilityPreferencesSealed, nameof(ShouldThrowOnCopyOrCutFailure), nameof(FrameworkCompatibilityPreferences))

What it means

Setting FrameworkCompatibilityPreferences.ShouldThrowOnCopyOrCutFailure after the preferences are sealed throws InvalidOperationException. This switch decides whether TextBoxBase.Copy/Cut throw when clipboard operations fail; like the other compatibility switches it is sealed once WPF starts reading it, so late writes are rejected.

Solutions

  1. Set the property at the very start of Main() before any WPF object is created
  2. Check IsSealed before assignment and log a warning if the setting cannot be applied
  3. If per-operation control is needed, wrap Copy/Cut calls in try-catch at the call site instead of using the switch

Example fix

// before
private void TextBox_CopyFailed(object s, EventArgs e)
{
    FrameworkCompatibilityPreferences.ShouldThrowOnCopyOrCutFailure = false; // throws
}

// after
static void Main()
{
    FrameworkCompatibilityPreferences.ShouldThrowOnCopyOrCutFailure = false;
    RunApp();
}
Defensive patterns

Strategy: validation

Validate before calling

if (!FrameworkCompatibilityPreferences.IsSealed)
    FrameworkCompatibilityPreferences.ShouldThrowOnCopyOrCutFailure = false;

Type guard

bool PrefsWritable => !FrameworkCompatibilityPreferences.IsSealed;

Try / catch

try { FrameworkCompatibilityPreferences.ShouldThrowOnCopyOrCutFailure = v; }
catch (InvalidOperationException) { /* sealed; handle clipboard failures at call sites instead */ }

Prevention

When it happens

Trigger: Assigning the static ShouldThrowOnCopyOrCutFailure property after FrameworkCompatibilityPreferences.IsSealed becomes true (post WPF initialization / first clipboard-related control use).

Common situations: Configuring clipboard failure behavior in a textbox event handler or after Application.Run rather than during process startup.

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/226537cfb6e32c33. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkCompatibilityPreferences.cs:376

        /// the application would take control of handling <see cref="System.Windows.Input.ApplicationCommands.Cut"/>
        /// and <see cref="System.Windows.Input.ApplicationCommands.Copy"/> RoutedUICommands through a 
        /// <see cref="System.Windows.Input.CommandBinding"/>, and apply that binding to all TextBoxBase
        /// controls (<see cref="System.Windows.Controls.TextBox"/> and <see cref="System.Windows.Controls.RichTextBox"/>) 
        /// in the application. The application should ensure that it handles ExternalExeptions arising from Copy/Cut 
        /// operations in the CommandBinding's Executed handler. 
        /// </remarks>
        public static bool ShouldThrowOnCopyOrCutFailure
        {
            get
            {
                return _shouldThrowOnCopyOrCutFailure;
            }

            set
            {
                if (_isSealed)
                {
                    throw new InvalidOperationException(
                        SR.Format(SR.CompatibilityPreferencesSealed, 
                        nameof(ShouldThrowOnCopyOrCutFailure), 
                        nameof(FrameworkCompatibilityPreferences)));
                }

                _shouldThrowOnCopyOrCutFailure = value;
            }
        }

        internal static bool GetShouldThrowOnCopyOrCutFailure()
        {
            Seal();
            return ShouldThrowOnCopyOrCutFailure;
        }

        private static void SetShouldThrowOnCopyOrCutFailuresFromAppSettings(NameValueCollection appSettings)
        {
            // user can use config file to enable this behavior change

View on GitHub (pinned to 81131a70a4)