dotnet/wpf · error · InvalidOperationException

SR.VisualCollection_ReadOnly

Error message

SR.VisualCollection_ReadOnly

What it means

Thrown by VisualCollection.VerifyNotReadOnly when a write operation is attempted on a read-only VisualCollection. WPF marks collections read-only in specific internal contexts (e.g. during enumeration or for system-owned collections), and any Add/Insert/Remove/Clear on them is invalid.

Solutions

  1. Check VisualCollection.IsReadOnly (or IsReadOnlyInternal) before mutating and skip/queue the change.
  2. Perform child modifications outside the read-only window (e.g. after Measure/Arrange completes, via Dispatcher).
  3. Add/remove children via the owning Visual's API on a UI thread at a safe point rather than inside iteration.

Example fix

// before
visuals.Add(newChild); // throws when collection is read-only
// after
if (!visuals.IsReadOnly)
{
    visuals.Add(newChild);
}
Defensive patterns

Strategy: validation

Validate before calling

if (visualCollection.IsReadOnly)
{
    // queue the mutation for later
}
else
{
    visualCollection.Add(child);
}

Type guard

static bool CanMutate(VisualCollection c) => !c.IsReadOnly;

Try / catch

try { collection.Add(child); }
catch (InvalidOperationException) { /* collection locked read-only; defer */ }

Prevention

When it happens

Trigger: Calling Add, Insert, Remove, RemoveAt, or Clear on a VisualCollection whose IsReadOnlyInternal is true — typically a collection obtained from a context where WPF has locked it (e.g. during read-only API paths like CopyTo's VerifyAPIReadOnly usage or system-driven visual management).

Common situations: Custom panels/framework code modifying children while WPF holds the collection read-only; writing to a visual's children inside layout or rendering callbacks that obtained the collection in a locked state.

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 dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/35850ca48cf8bacb. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/VisualCollection.cs:98

        internal void VerifyAPIReadWrite()
        {
            Debug.Assert(_owner != null);
            _owner.VerifyAPIReadWrite();
            VerifyNotReadOnly();
        }

        internal void VerifyAPIReadWrite(Visual other)
        {
            Debug.Assert(_owner != null);
            _owner.VerifyAPIReadWrite(other);
            VerifyNotReadOnly();
        }

        internal void VerifyNotReadOnly()
        {
            if (IsReadOnlyInternal)
            {
                throw new InvalidOperationException(SR.VisualCollection_ReadOnly); 
            }
        }

        /// <summary>
        /// Gets the number of elements in the collection.
        /// </summary>
        public int Count
        {
            get
            {
                VerifyAPIReadOnly();

                return InternalCount;
            }
        }

        /// <summary>
        /// True if the collection allows modifications, otherwise false.

View on GitHub (pinned to 81131a70a4)