dotnet/wpf · error · InvalidOperationException
SR.Format(SR.Freezable_CloneInvalidType, typeof(T).Name)
Error message
SR.Format(SR.Freezable_CloneInvalidType, typeof(T).Name)
What it means
CloneCommon throws InvalidOperationException(SR.Freezable_CloneInvalidType) when cloning a FreezableCollection whose element type T cannot be cloned: the item is neither Freezable nor ICloneable (or otherwise not handled by the CloneCommonType switch), so the cloned item newValue remains null. It indicates T is a type the clone machinery cannot deep-copy.
Solutions
- Make T a Freezable-derived type (override CloneCore/CloneCurrentValueCore) so the clone machinery can copy elements.
- Implement cloning support for T (Freezable) instead of a plain class.
- Perform a manual copy (foreach item, create and populate a new instance) rather than calling Clone.
Example fix
// before
class MyItem { public int X; }
var col = new FreezableCollection<MyItem>();
var copy = col.Clone(); // throws
// after
class MyItem : Freezable {
public int X { get; set; }
protected override Freezable CreateInstanceCore() => new MyItem();
protected override void CloneCore(Freezable source) { X = ((MyItem)source).X; }
} Defensive patterns
Strategy: validation
Validate before calling
bool cloneable = typeof(Freezable).IsAssignableFrom(typeof(T)) || typeof(ICloneable).IsAssignableFrom(typeof(T));
if (!cloneable) throw new InvalidOperationException($"{typeof(T).Name} cannot be cloned; derive it from Freezable."); Type guard
static bool IsCloneableElement<T>() => typeof(Freezable).IsAssignableFrom(typeof(T)) || typeof(ICloneable).IsAssignableFrom(typeof(T));
Try / catch
try { var copy = collection.Clone(); }
catch (InvalidOperationException ex) { /* fall back to manual copy of elements */ } Prevention
- Constrain FreezableCollection<T> element types to Freezable subclasses
- Implement CreateInstanceCore and CloneCore on custom element types
- Test Clone/GetAsFrozen on every collection type you ship
When it happens
Trigger: Calling Clone/CloneCore/CloneCurrentValueCore/GetAsFrozen/GetCurrentValueAsFrozen on a FreezableCollection<T> where T is not Freezable and lacks a supported clone path, e.g. FreezableCollection<SomePoco> or a custom type not deriving from Freezable.
Common situations: Declaring FreezableCollection<T> with a plain business object for convenience, then freezing/cloning the collection for animation or thread marshalling; SDK retargeting where a custom element type lost its Freezable base.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- IAnimatable_CantAnimateSealedDO
- Property data must be a non-reference variant compatible…
- SR.Collection_BadRank
- SR.Collection_NoNull
- SR.Collection_NoNull
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/cf80007a1865ba2a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/FreezableCollection.cs:826
newValue = itemAsFreezable.Clone() as T;
break;
case CloneCommonType.CloneCurrentValue:
newValue = itemAsFreezable.CloneCurrentValue() as T;
break;
case CloneCommonType.GetAsFrozen:
newValue = itemAsFreezable.GetAsFrozen() as T;
break;
case CloneCommonType.GetCurrentValueAsFrozen:
newValue = itemAsFreezable.GetCurrentValueAsFrozen() as T;
break;
default:
Invariant.Assert(false, "Invalid CloneCommonType encountered.");
break;
}
if (newValue == null)
{
throw new InvalidOperationException(SR.Format(SR.Freezable_CloneInvalidType, typeof(T).Name));
}
}
OnFreezablePropertyChanged(oldValue: null, newValue);
_collection.Add(newValue);
}
}
/// <summary>
/// Implementation of Freezable.CloneCore()
/// </summary>
protected override void CloneCore(Freezable source)
{
base.CloneCore(source);
FreezableCollection<T> sourceFreezableCollection = (FreezableCollection<T>) source;
CloneCommon(sourceFreezableCollection, CloneCommonType.Clone);View on GitHub (pinned to 81131a70a4)