{"record":{"id":"2014195c0ff602ee","repo":"thebookisclosed/ViVe","slug":"0-1-is-an-immutable-priority-and-can-t-be-written-to","errorCode":null,"errorMessage":"{0} ({1}) is an immutable priority and can't be written to.","messagePattern":"(.+?) \\((.+?)\\) is an immutable priority and can't be written to\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"ViVe/FeatureManager.cs","lineNumber":94,"sourceCode":"            return config;\n        }\n\n        public static ulong QueryFeatureConfigurationChangeStamp()\n        {\n            return Ntdll.RtlQueryFeatureConfigurationChangeStamp();\n        }\n\n        public static int SetFeatureConfigurations(RTL_FEATURE_CONFIGURATION_UPDATE[] updates, RTL_FEATURE_CONFIGURATION_TYPE configurationType = RTL_FEATURE_CONFIGURATION_TYPE.Runtime)\n        {\n            ulong dummy = 0;\n            return SetFeatureConfigurations(updates, configurationType, ref dummy);\n        }\n\n        public static int SetFeatureConfigurations(RTL_FEATURE_CONFIGURATION_UPDATE[] updates, RTL_FEATURE_CONFIGURATION_TYPE configurationType, ref ulong previousChangeStamp)\n        {\n            foreach (var update in updates)\n                if (ImmutablePriorities.Contains(update.Priority))\n                    throw new ArgumentException(string.Format(\"{0} ({1}) is an immutable priority and can't be written to.\", update.Priority, (int)update.Priority));\n                else if (update.Priority == RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy && !update.UserPolicyPriorityCompatible)\n                    throw new ArgumentException(\"UserPolicy priority overrides do not support persisting properties other than EnabledState.\");\n\n            if (configurationType == RTL_FEATURE_CONFIGURATION_TYPE.Runtime)\n                return Ntdll.RtlSetFeatureConfigurations(ref previousChangeStamp, RTL_FEATURE_CONFIGURATION_TYPE.Runtime, updates, updates.Length);\n            else\n                return SetFeatureConfigurationsInRegistry(updates, previousChangeStamp);\n        }\n\n        public static IntPtr RegisterFeatureConfigurationChangeNotification(FeatureConfigurationChangeCallback callback)\n        {\n            return RegisterFeatureConfigurationChangeNotification(callback, IntPtr.Zero);\n        }\n\n        public static IntPtr RegisterFeatureConfigurationChangeNotification(FeatureConfigurationChangeCallback callback, IntPtr context)\n        {\n            Ntdll.RtlRegisterFeatureConfigurationChangeNotification(callback, context, IntPtr.Zero, out IntPtr sub);\n            return sub;","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/thebookisclosed/ViVe/blob/3f8c6a3425983412da1e8b26cd757c3aa17b3f25/ViVe/FeatureManager.cs#L76-L112","documentation":"ViVe's SetFeatureConfigurations rejects any update whose Priority is in the ImmutablePriorities set, because those priority levels are reserved and managed by Windows itself; writing to them via RtlSetFeatureConfigurations would corrupt system-managed feature state. The exception is an ArgumentException thrown before any native call is made, and the message names both the offending priority value and its integer representation.","triggerScenarios":"Calling ViVe.Feature.FeatureManager.SetFeatureConfigurations with an RTL_FEATURE_CONFIGURATION_UPDATE whose Priority property is set to one of the immutable priorities (e.g. a system/reserved priority level) — detected by ImmutablePriorities.Contains(update.Priority) in the foreach loop before the native call.","commonSituations":"Developers constructing feature configuration updates manually and guessing at priority values; copying configurations read from the system (which may carry immutable priorities) and writing them back unmodified; tooling that bulk-applies saved .vcdi/dump states that include OS-managed priority entries.","solutions":["Set the update's Priority to a writable priority such as UserPolicy instead of an immutable one","Filter out updates whose Priority is in FeatureManager.ImmutablePriorities before calling SetFeatureConfigurations","If replaying a saved configuration, rebuild each update with only user-writable fields and a user-writable priority"],"exampleFix":"// before\nvar update = new RTL_FEATURE_CONFIGURATION_UPDATE { FeatureId = id, Priority = RTL_FEATURE_CONFIGURATION_PRIORITY.OS }; // immutable\n// after\nvar update = new RTL_FEATURE_CONFIGURATION_UPDATE { FeatureId = id, Priority = RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy, EnabledState = RTL_FEATURE_ENABLED_STATE.Enabled, UserPolicyPriorityCompatible = true };","handlingStrategy":"validation","validationCode":"if (ViVe.Feature.FeatureManager.ImmutablePriorities.Contains(update.Priority))\n    throw new InvalidOperationException($\"Priority {update.Priority} is system-managed; use a writable priority such as UserPolicy.\");","typeGuard":"static bool IsWritablePriority(RTL_FEATURE_CONFIGURATION_PRIORITY p) =>\n    !ViVe.Feature.FeatureManager.ImmutablePriorities.Contains(p);","tryCatchPattern":"try\n{\n    ViVe.Feature.FeatureManager.SetFeatureConfigurations(updates, RTL_FEATURE_CONFIGURATION_TYPE.Runtime, ref stamp);\n}\ncatch (ArgumentException ex) when (ex.Message.Contains(\"immutable priority\"))\n{\n    // log and drop or rewrite the offending update\n}","preventionTips":["Check ImmutablePriorities before constructing updates","Never write back priorities read from system state verbatim","Use only documented RTL_FEATURE_CONFIGURATION_PRIORITY members"],"tags":["csharp","windows","feature-management","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"3f8c6a3425983412da1e8b26cd757c3aa17b3f25","analyzedAt":"2026-09-14T11:10:27.021Z","contentChangedAt":"2026-09-14T11:10:27.021Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}