dotnet/aspnetcore · error · InvalidOperationException

Cannot notify about changes because the

Error message

Cannot notify about changes because the {GetType()} is configured as fixed.

What it means

CascadingValueSource created with isFixed=true is designed to never change. Calling NotifyChangedAsync on it is a programming error because fixed sources skip subscription tracking, so there is nothing to notify.

Solutions

  1. Create the source with isFixed: false if you need change notifications.
  2. Remove the NotifyChangedAsync call on the fixed source.
  3. If the value must change, replace the source instance entirely instead of notifying.

Example fix

// before
var src = new CascadingValueSource<string>("v", isFixed: true);
await src.NotifyChangedAsync();
// after
var src = new CascadingValueSource<string>("v", isFixed: false);
src.Value = "v2";
await src.NotifyChangedAsync();
Defensive patterns

Strategy: validation

Validate before calling

// Track whether the source is fixed and skip notify calls accordingly.
if (!sourceIsFixed)
{
    await source.NotifyChangedAsync();
}

Prevention

When it happens

Trigger: new CascadingValueSource<T>(value, isFixed: true) followed by a call to .NotifyChangedAsync().

Common situations: Refactoring a non-fixed source to fixed without removing notify calls, copying code from a dynamic source, or misunderstanding the isFixed contract.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/da48d3cee1cc3869. Report an issue: GitHub.

Appendix: source

Thrown at src/Components/Components/src/CascadingValueSource.cs:89

    private CascadingValueSource(bool isFixed)
    {
        _isFixed = isFixed;

        if (!_isFixed)
        {
            _subscribers = new();
        }
    }

    /// <summary>
    /// Notifies subscribers that the value has changed (for example, if it has been mutated).
    /// </summary>
    /// <returns>A <see cref="Task"/> that completes when the notifications have been issued.</returns>
    public Task NotifyChangedAsync()
    {
        if (_isFixed)
        {
            throw new InvalidOperationException($"Cannot notify about changes because the {GetType()} is configured as fixed.");
        }

        if (_subscribers?.Count > 0)
        {
            var tasks = new List<Task>();

            foreach (var (dispatcher, subscribers) in _subscribers)
            {
                tasks.Add(dispatcher.InvokeAsync(() =>
                {
                    var subscribersBuffer = new ComponentStateBuffer();
                    var subscribersCount = subscribers.Count;
                    var subscribersCopy = subscribersCount <= ComponentStateBuffer.Capacity
                        ? subscribersBuffer[..subscribersCount]
                        : new ComponentState[subscribersCount];
                    subscribers.CopyTo(subscribersCopy);

                    // We iterate over a copy of the list because new subscribers might get

View on GitHub (pinned to 3600ca084e)