{"record":{"id":"d0d68a5d320afbef","repo":"tui-cs/Terminal.Gui","slug":"cloning-of-immutable-collections-like-type-name","errorCode":null,"errorMessage":"Cloning of immutable collections like {type.Name} is not supported.","messagePattern":"Cloning of immutable collections like (.+?) is not supported\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"Terminal.Gui/Configuration/DeepCloner.cs","lineNumber":219,"sourceCode":"            newArray.SetValue (clonedValue, i);\n        }\n\n        return newArray;\n    }\n\n    [UnconditionalSuppressMessage (\"Trimming\", \"IL2072\", Justification = \"Collection cloning only instantiates the runtime collection type after filtering to supported IList implementations.\")]\n    private static object CloneCollection (object source, ConcurrentDictionary<object, object> visited)\n    {\n        Type type = source.GetType ();\n\n        // Check for immutable collections and throw if found\n        if (type.IsGenericType)\n        {\n            Type genericTypeDef = type.GetGenericTypeDefinition ();\n\n            if (genericTypeDef.FullName != null && genericTypeDef.FullName.StartsWith (\"System.Collections.Immutable\"))\n            {\n                throw new NotSupportedException ($\"Cloning of immutable collections like {type.Name} is not supported.\");\n            }\n        }\n\n        if (source is not IList)\n        {\n            throw new NotSupportedException ($\"Cloning of collection type {type.Name} is not supported unless it implements IList.\");\n        }\n\n        if (Activator.CreateInstance (type) is not IList tempList)\n        {\n            throw new NotSupportedException ($\"Cloning of collection type {type.Name} is not supported without a parameterless constructor.\");\n        }\n\n        // Add to visited before cloning contents to prevent circular reference issues\n        visited.TryAdd (source, tempList);\n\n        foreach (object? item in (IEnumerable)source)\n        {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/Configuration/DeepCloner.cs#L201-L237","documentation":"Thrown by DeepCloner.CloneCollection when the source collection's runtime type is a generic type whose FullName starts with \"System.Collections.Immutable\" (ImmutableArray, ImmutableDictionary, etc.). DeepCloner deliberately refuses to clone immutable collections — they are structurally non-mutable so a memberwise clone-into-new-instance strategy cannot work.","triggerScenarios":"A [ConfigurationProperty] value (or a nested member of one) is an immutable collection from System.Collections.Immutable, and DeepCloner reaches CloneCollection for it during Apply.","commonSituations":"Storing an ImmutableDictionary or ImmutableArray as a config property value; a config type that exposes an immutable collection that DeepCloner traverses.","solutions":["Do not use System.Collections.Immutable collection types for [ConfigurationProperty] values; use mutable List/Dictionary/ConcurrentDictionary instead.","If immutability is required at the API surface, store a mutable collection internally and expose an immutable view.","Convert the immutable collection to a mutable one before assigning it as a config value."],"exampleFix":"// before\n[ConfigurationProperty] public static ImmutableDictionary<string, Scheme>? Schemes { get; set; }\n// after\n[ConfigurationProperty] public static Dictionary<string, Scheme>? Schemes { get; set; }","handlingStrategy":"validation","validationCode":"Type t = source.GetType ();\nif (t.IsGenericType && t.GetGenericTypeDefinition ().FullName?.StartsWith (\"System.Collections.Immutable\") == true)\n    throw new NotSupportedException ($\"Refusing to clone immutable collection {t.Name}; use a mutable collection.\");","typeGuard":"static bool IsImmutableCollection (Type t) =>\n    t.IsGenericType\n    && t.GetGenericTypeDefinition ().FullName?.StartsWith (\"System.Collections.Immutable\", StringComparison.Ordinal) == true;","tryCatchPattern":"try { ConfigurationManager.Apply (); }\ncatch (NotSupportedException ex) when (ex.Message.Contains (\"immutable collections\"))\n{ /* switch the config property to a mutable collection type */ }","preventionTips":["Do not use System.Collections.Immutable types as config property values.","Prefer List<T>, Dictionary<,>, ConcurrentDictionary<,> for config."],"tags":["configuration","deepcloner","immutable-collections","notsupported"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}