OrchardCMS/OrchardCore · error · NotSupportedException

AlternateCollection can't be changed.

Error message

AlternateCollection can't be changed.

What it means

AlternatesCollection is an immutable collection with a shared Empty singleton. Any mutation (Add, Remove, Clear, AddRange) on the Empty instance calls EnsureMutable, which throws NotSupportedException because the singleton must never change. Mutations must go through a mutable copy of the collection.

Solutions

  1. Assign a new mutable collection first: shape.Metadata.Alternates = new AlternatesCollection(existing); then mutate
  2. Use the collection's non-mutating APIs or create a new AlternatesCollection with the added items
  3. Initialize alternates when the shape is built (before it reaches the sealed/Empty state)
  4. Check for existing items and replace the Alternates reference rather than mutating the shared Empty

Example fix

// before
shape.Metadata.Alternates.Add(shape.Metadata.Type + "_Custom");
// after
shape.Metadata.Alternates = new AlternatesCollection(
    shape.Metadata.Alternates.Append(shape.Metadata.Type + "_Custom"));
Defensive patterns

Strategy: validation

Validate before calling

if (shape.Metadata.Alternates == AlternatesCollection.Empty)
{
    shape.Metadata.Alternates = new AlternatesCollection();
}
shape.Metadata.Alternates.Add(alternateName);

Type guard

bool AlternatesMutable(IShape shape) => shape.Metadata.Alternates != AlternatesCollection.Empty;

Try / catch

try { alternates.Add(name); } catch (NotSupportedException) { shape.Metadata.Alternates = new AlternatesCollection(alternates.Append(name)); }

Prevention

When it happens

Trigger: Calling shape.Metadata.Alternates.Add(...), .Remove(...), .Clear(), or .AddRange(...) when Alternates is the static Empty collection — typically on a freshly created shape whose alternates were never initialized, or after alternates were sealed.

Common situations: Custom shape-metadata providers or handlers appending alternates during rendering; code assuming Alternates is always a mutable List<string>; adding placement alternates late in the pipeline.

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


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/c0d15d396b595adb. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.DisplayManagement/Shapes/AlternatesCollection.cs:105

    }

    public void AddRange(IEnumerable<string> alternates)
    {
        ArgumentNullException.ThrowIfNull(alternates);

        EnsureMutable();

        foreach (var alternate in alternates)
        {
            Add(alternate);
        }
    }

    private void EnsureMutable()
    {
        if (this == Empty)
        {
            throw new NotSupportedException("AlternateCollection can't be changed.");
        }
    }

    public IEnumerator<string> GetEnumerator()
        => _items.Values.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator()
        => _items.Values.GetEnumerator();
}

View on GitHub (pinned to 4306c0717f)