tui-cs/Terminal.Gui · error · InvalidOperationException

Cannot create instance of type {type.FullName}. No parameter

Error message

Cannot create instance of type {type.FullName}. No parameterless constructor or clone method found.

What it means

Thrown by DeepCloner.CreateInstance when a type has no public parameterless constructor and (in AOT) no JsonTypeInfo is available to deserialize "{}". DeepCloner is used by ConfigProperty.Apply to deep-clone property values before writing them; if the value's runtime type cannot be instantiated, cloning fails. This is an InvalidOperationException about the cloned type, not the config value itself.

Source

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

        {
            // Try parameterless constructor
            if (type.GetConstructor (Type.EmptyTypes) != null)
            {
                return Activator.CreateInstance (type)!;
            }

            // In AOT, try using the JsonSerializer if available
            if (IsAotEnvironment ())
            {
                JsonTypeInfo? jsonTypeInfo = TuiSerializerContext.Instance.GetTypeInfo (type);

                if (jsonTypeInfo is not null)
                {
                    return JsonSerializer.Deserialize ("{}", jsonTypeInfo)!;
                }
            }

            throw new InvalidOperationException ($"Cannot create instance of type {type.FullName}. No parameterless constructor or clone method found.");
        }
        catch (MissingMethodException)
        {
            throw new InvalidOperationException (
                                                 $"Cannot create instance of type {type.FullName} in AOT context. Consider adding this type to your SourceGenerationContext.");
        }
    }

    private static object CloneArray (object source, ConcurrentDictionary<object, object> visited)
    {
        Array array = (Array)source;
        Array newArray = (Array)array.Clone ();
        visited.TryAdd (source, newArray);

        for (var i = 0; i < array.Length; i++)
        {
            object? value = array.GetValue (i);
            object? clonedValue = DeepCloneInternal (value, visited);

View on GitHub (pinned to 2e47b11478)

Solutions

  1. Add a public parameterless constructor to the type held by the config property.
  2. If the type is immutable by design, give it ICloneable or a Clone() method (DeepCloner checks for those first), or implement a copy constructor DeepCloner can find.
  3. Under NativeAOT, add the type to your SourceGenerationContext / TuiSerializerContext so the JsonSerializer fallback works.
  4. Avoid storing types DeepCloner cannot handle as [ConfigurationProperty] values.

Example fix

// before
public class MyConfig { public MyConfig(int x) {} }
// after
public class MyConfig
{
    public MyConfig () {}
    public MyConfig (int x) {}
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject config property types without a parameterless ctor at registration time.
Type t = configProperty.PropertyInfo!.PropertyType;
if (t.GetConstructor (Type.EmptyTypes) is null
    && typeof (ICloneable).IsAssignableFrom (t) == false)
    throw new InvalidOperationException ($"{t} has no parameterless ctor or Clone; DeepCloner will fail.");

Type guard

static bool IsDeepCloneable (Type t) =>
    t.GetConstructor (Type.EmptyTypes) is not null
    || typeof (ICloneable).IsAssignableFrom (t)
    || t.GetMethod ("Clone", Type.EmptyTypes) is not null;

Try / catch

try { ConfigurationManager.Apply (); }
catch (InvalidOperationException ex) when (ex.Message.Contains ("No parameterless constructor"))
{ /* add a default ctor to the offending type */ }

Prevention

When it happens

Trigger: A [ConfigurationProperty] holds a value whose type lacks a parameterless constructor (e.g. a struct with only a parameterized ctor, a record with required init properties and no default ctor, or a type not registered for AOT source generation).

Common situations: Adding a custom configuration property whose type has no default constructor; running under NativeAOT/trimming where reflection-based instantiation is unavailable and the type was not added to TuiSerializerContext.

Related errors


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