{"record":{"id":"9d641e35dd35e2ed","repo":"dotnet/wpf","slug":"sr-changingtypenotallowed","errorCode":null,"errorMessage":"SR.ChangingTypeNotAllowed","messagePattern":"SR\\.ChangingTypeNotAllowed","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ComponentResourceKey.cs","lineNumber":54,"sourceCode":"            _resourceIdInitialized = true;\n        }\n\n        /// <summary>\n        ///     The Type associated with this resources. Must be in assembly where the resource is located.\n        /// </summary>\n        public Type TypeInTargetAssembly\n        {\n            get\n            {\n                return _typeInTargetAssembly;\n            }\n\n            set\n            {\n                ArgumentNullException.ThrowIfNull(value);\n                if (_typeInTargetAssemblyInitialized)\n                {\n                    throw new InvalidOperationException(SR.ChangingTypeNotAllowed);\n                }\n                _typeInTargetAssembly = value;\n                _typeInTargetAssemblyInitialized = true;\n            }\n        }\n\n        /// <summary>\n        ///     Used to determine where to look for the resource dictionary that holds this resource.\n        /// </summary>\n        public override Assembly Assembly\n        {\n            get\n            {\n                return _typeInTargetAssembly?.Assembly;\n            }\n        }\n\n        /// <summary>","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ComponentResourceKey.cs#L36-L72","documentation":"ComponentResourceKey.TypeInTargetAssembly is a once-only init-only style property: once it has been set (or set via the constructor), assigning it again throws InvalidOperationException. WPF enforces this because the key is typically used in resource dictionaries and changing the type after use would corrupt dictionary lookups.","triggerScenarios":"Assigning ComponentResourceKey.TypeInTargetAssembly a second time on the same instance after it was already set in the constructor or a previous assignment.","commonSituations":"Reusing a cached ComponentResourceKey instance across themes or assemblies and trying to retarget its TypeInTargetAssembly; initializing a shared key in XAML and then overwriting it in code-behind.","solutions":["Create a new ComponentResourceKey instead of mutating the existing one's TypeInTargetAssembly","Set TypeInTargetAssembly only once, at construction time via the (Type, object) constructor","Check the _typeInTargetAssemblyInitialized state (or track it yourself) before assigning"],"exampleFix":"// before\nkey.TypeInTargetAssembly = typeof(Other); // throws after already set\n// after\nvar newKey = new ComponentResourceKey(typeof(Other), key.ResourceId);","handlingStrategy":"validation","validationCode":"if (!isKeyInitialized(key)) { key.TypeInTargetAssembly = targetType; } // track init yourself, or just construct a new key","typeGuard":"bool IsKeyInitialized(ComponentResourceKey k) => !ReferenceEquals(k, null) && k.ResourceId != null; // approximation; prefer constructing new keys","tryCatchPattern":"try { key.TypeInTargetAssembly = t; } catch (InvalidOperationException ex) { /* key already initialized: create new key */ }","preventionTips":["Treat ComponentResourceKey as immutable: set everything in the constructor","Never share/mutate key instances across assemblies or themes","Prefer new ComponentResourceKey(type, id) over property mutation"],"tags":["wpf","resources","invalid-operation","immutable-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}