dotnet/wpf · error · InvalidOperationException
SR.Format(SR.CompatibilityPreferencesSealed…
Error message
SR.Format(SR.CompatibilityPreferencesSealed, "IsVirtualizingStackPanel_45Compatible", "FrameworkCompatibilityPreferences")
What it means
Setting FrameworkCompatibilityPreferences.IsVirtualizingStackPanel_45Compatible after the preferences are sealed throws InvalidOperationException. This switch controls whether VirtualizingStackPanel uses .NET 4.5-compatible behavior; WPF seals it once virtualization code has read the preference so panel behavior cannot change mid-run.
Solutions
- Move the assignment to the first line of Main(), before any WPF type is loaded
- Guard the assignment with a check of FrameworkCompatibilityPreferences.IsSealed
- Remove the runtime toggle and fix the value at build/startup time
Example fix
// before
protected override void OnStartup(StartupEventArgs e)
{
FrameworkCompatibilityPreferences.IsVirtualizingStackPanel_45Compatible = false; // may already be sealed
}
// after
static void Main()
{
FrameworkCompatibilityPreferences.IsVirtualizingStackPanel_45Compatible = false;
var app = new App();
app.Run();
} Defensive patterns
Strategy: validation
Validate before calling
if (!FrameworkCompatibilityPreferences.IsSealed)
FrameworkCompatibilityPreferences.IsVirtualizingStackPanel_45Compatible = false; Type guard
bool PrefsWritable => !FrameworkCompatibilityPreferences.IsSealed;
Try / catch
try { FrameworkCompatibilityPreferences.IsVirtualizingStackPanel_45Compatible = v; }
catch (InvalidOperationException ex) { log.Warn(ex); } Prevention
- Set the switch before any ItemsControl/VirtualizingStackPanel is created
- Centralize all compatibility settings in one early startup method
- Add a debug assert on IsSealed after the startup method runs
When it happens
Trigger: Assigning the static IsVirtualizingStackPanel_45Compatible property after WPF has been initialized (first list/virtualization usage, Dispatcher started, or IsSealed == true).
Common situations: Setting the switch in a page/window constructor, or attempting to change virtualization behavior after the app has rendered its first VirtualizingStackPanel-based list.
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
- AnchorItem ' ' does not have a realized container and hence…
- Cannot reopen a popup in the closed event handler.
- Microsoft.Windows.Controls.SR.VirtualizedElement
- SR.AnnotationServiceNotEnabled
- SR.CollectionViewTypeIsInitOnly
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f5d134055bbb173c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkCompatibilityPreferences.cs:244
// The 4.5 algorithm had many flaws, leading to infinite loops, scrolling
// to the wrong place, and other bad symptoms. DDCC is worried that fixing
// these issues may introduce new compat problems, and asked for a way to opt out
// of the fixes. To opt out, add an entry to the <appSettings> section of the
// app config file:
// <add key="IsVirtualizingStackPanel_45Compatible" value="true"/>
private static bool _vsp45Compat = false;
internal static bool VSP45Compat
{
get { return _vsp45Compat; }
set
{
lock (_lockObject)
{
if (_isSealed)
{
throw new InvalidOperationException(SR.Format(SR.CompatibilityPreferencesSealed, "IsVirtualizingStackPanel_45Compatible", "FrameworkCompatibilityPreferences"));
}
_vsp45Compat = value;
}
}
}
internal static bool GetVSP45Compat()
{
Seal();
return VSP45Compat;
}
private static void SetVSP45CompatFromAppSettings(NameValueCollection appSettings)
{
// user can use config file to opt out of VSP fixes
string s = appSettings["IsVirtualizingStackPanel_45Compatible"];View on GitHub (pinned to 81131a70a4)