dotnet/wpf · error · InvalidOperationException

SR.ChangingIdNotAllowed

Error message

SR.ChangingIdNotAllowed

What it means

ComponentResourceKey.ResourceId is likewise write-once: once _resourceIdInitialized is true, a second assignment throws InvalidOperationException. The key's identity must remain stable once created so resource dictionary lookups are consistent.

Solutions

  1. Create a new ComponentResourceKey with the desired ResourceId
  2. Set ResourceId exactly once, at construction
  3. Track initialization before assigning

Example fix

// before
sharedKey.ResourceId = "OtherId"; // throws
// after
var newKey = new ComponentResourceKey(typeof(MyClass), "OtherId");
Defensive patterns

Strategy: validation

Validate before calling

if (key.ResourceId == null) { key.ResourceId = id; } else { key = new ComponentResourceKey(key.TypeInTargetAssembly, id); }

Try / catch

try { key.ResourceId = id; } catch (InvalidOperationException) { key = new ComponentResourceKey(key.TypeInTargetAssembly, id); }

Prevention

When it happens

Trigger: Assigning ComponentResourceKey.ResourceId when it was already initialized (via constructor or a previous set).

Common situations: Mutating a shared/static key instance to point at a different resource id; XAML defining the ResourceId then code-behind reassigning it.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/3b07a2afaf183a4a. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ComponentResourceKey.cs:86

                return _typeInTargetAssembly?.Assembly;
            }
        }

        /// <summary>
        ///     A unique Id to differentiate this key from other keys associated with the same type.
        /// </summary>
        public object ResourceId
        {
            get
            {
                return _resourceId;
            }

            set
            {
                if (_resourceIdInitialized)
                {
                    throw new InvalidOperationException(SR.ChangingIdNotAllowed);
                }
                _resourceId = value;
                _resourceIdInitialized = true;
            }
        }

        /// <summary>
        ///     Determines if the passed in object is equal to this object.
        ///     Two keys will be equal if they both have equal Types and IDs.
        /// </summary>
        /// <param name="o">The object to compare with.</param>
        /// <returns>True if the objects are equal. False otherwise.</returns>
        public override bool Equals(object o)
        {
            ComponentResourceKey key = o as ComponentResourceKey;

            if (key != null)
            {

View on GitHub (pinned to 81131a70a4)