tui-cs/Terminal.Gui · error · NotSupportedException

Cloning of immutable collections like {type.Name} is not sup

Error message

Cloning of immutable collections like {type.Name} is not supported.

What it means

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.

Source

Thrown at Terminal.Gui/Configuration/DeepCloner.cs:219

            newArray.SetValue (clonedValue, i);
        }

        return newArray;
    }

    [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "Collection cloning only instantiates the runtime collection type after filtering to supported IList implementations.")]
    private static object CloneCollection (object source, ConcurrentDictionary<object, object> visited)
    {
        Type type = source.GetType ();

        // Check for immutable collections and throw if found
        if (type.IsGenericType)
        {
            Type genericTypeDef = type.GetGenericTypeDefinition ();

            if (genericTypeDef.FullName != null && genericTypeDef.FullName.StartsWith ("System.Collections.Immutable"))
            {
                throw new NotSupportedException ($"Cloning of immutable collections like {type.Name} is not supported.");
            }
        }

        if (source is not IList)
        {
            throw new NotSupportedException ($"Cloning of collection type {type.Name} is not supported unless it implements IList.");
        }

        if (Activator.CreateInstance (type) is not IList tempList)
        {
            throw new NotSupportedException ($"Cloning of collection type {type.Name} is not supported without a parameterless constructor.");
        }

        // Add to visited before cloning contents to prevent circular reference issues
        visited.TryAdd (source, tempList);

        foreach (object? item in (IEnumerable)source)
        {

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Do not use System.Collections.Immutable collection types for [ConfigurationProperty] values; use mutable List/Dictionary/ConcurrentDictionary instead.
  2. If immutability is required at the API surface, store a mutable collection internally and expose an immutable view.
  3. Convert the immutable collection to a mutable one before assigning it as a config value.

Example fix

// before
[ConfigurationProperty] public static ImmutableDictionary<string, Scheme>? Schemes { get; set; }
// after
[ConfigurationProperty] public static Dictionary<string, Scheme>? Schemes { get; set; }
Defensive patterns

Strategy: validation

Validate before calling

Type t = source.GetType ();
if (t.IsGenericType && t.GetGenericTypeDefinition ().FullName?.StartsWith ("System.Collections.Immutable") == true)
    throw new NotSupportedException ($"Refusing to clone immutable collection {t.Name}; use a mutable collection.");

Type guard

static bool IsImmutableCollection (Type t) =>
    t.IsGenericType
    && t.GetGenericTypeDefinition ().FullName?.StartsWith ("System.Collections.Immutable", StringComparison.Ordinal) == true;

Try / catch

try { ConfigurationManager.Apply (); }
catch (NotSupportedException ex) when (ex.Message.Contains ("immutable collections"))
{ /* switch the config property to a mutable collection type */ }

Prevention

When it happens

Trigger: 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.

Common situations: Storing an ImmutableDictionary or ImmutableArray as a config property value; a config type that exposes an immutable collection that DeepCloner traverses.

Related errors


AI-assisted analysis of tui-cs/Terminal.Gui@2e47b11478 (2026-08-13). Data as JSON: /api/errors/d0d68a5d320afbef. Report an issue: GitHub.