dotnet/wpf · error · InvalidOperationException
SR.Freezable_CantFreeze
Error message
SR.Freezable_CantFreeze
What it means
Freezable.Freeze() makes the object immutable, but only if every part of the object graph is freezable (CanFreeze is true — no databound or mutable sub-objects remain). The public Freeze() first checks CanFreeze and throws InvalidOperationException(SR.Freezable_CantFreeze) when the check fails, guaranteeing the freeze operation will succeed before mutating state.
Solutions
- Check CanFreeze before calling Freeze and skip/clone the object when it returns false
- Remove or replace non-freezable members (Bindings, DynamicResource references, animated values) with fixed values
- Use GetAsFrozen/GetCurrentValueAsFrozen appropriately and handle the failure path
- Clone the Freezable and simplify it until CanFreeze returns true
Example fix
// before
brush.Freeze(); // throws if animated
// after
if (brush.CanFreeze) brush.Freeze();
else { var frozen = brush.GetCurrentValueAsFrozen() as SolidColorBrush; } Defensive patterns
Strategy: validation
Validate before calling
if (freezable.CanFreeze) freezable.Freeze(); else { /* clone/simplify first */ } Type guard
static bool CanSafelyFreeze(System.Windows.Freezable f) => f.CanFreeze && !f.IsFrozen;
Try / catch
try { obj.Freeze(); }
catch (InvalidOperationException ex) { log.Warn($"{obj} cannot be frozen: {ex.Message}"); } Prevention
- Always check CanFreeze before Freeze/GetAsFrozen
- Avoid Bindings/DynamicResource inside objects you intend to freeze
- Replace animated values with fixed values before freezing for cross-thread sharing
When it happens
Trigger: Calling Freeze() (or GetAsFrozen) on a Freezable whose CanFreeze is false — e.g. a Brush or Geometry containing non-frozen sub-objects, an animation with unresolved bindings, or a Freezable still registered to change handlers.
Common situations: Freezing a SolidColorBrush whose Color is animated, a Pen referencing a non-freezable brush, or any resource defined in XAML with DynamicResource/Binding inside; attempting to freeze resources for cross-thread sharing in performance work.
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
- SR.Format(SR.CrossThreadAccessOfUnshareableFreezable…
- SR.Format(SR.Freezable_CantBeFrozen, GetType().FullName)
- SR.Freezable_AttemptToUseInnerValueWithDifferentThread
- ElementNotAvailableException
- IAnimatable_CantAnimateSealedDO
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/003fb3b5c69d8781.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Freezable.cs:172
get
{
return IsFrozenInternal || FreezeCore(isChecking: true);
}
}
/// <summary>
/// Does an in-place modification to make the object frozen. It is legal to
/// call this on values that are already frozen.
/// </summary>
/// <exception cref="System.InvalidOperationException">This exception
/// will be thrown if this Freezable can't be frozen. Use
/// the CanFreeze property to detect this in advance.</exception>
public void Freeze()
{
// Check up front that the operation will succeed before we begin.
if (!CanFreeze)
{
throw new InvalidOperationException(SR.Freezable_CantFreeze);
}
Freeze(isChecking: false);
}
#endregion
#region Public Properties
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
/// <summary>
/// Returns whether or not the Freezable is modifiable. Attempts
/// to set properties on an IsFrozen value resultView on GitHub (pinned to 81131a70a4)