thebookisclosed/ViVe · error · ArgumentException

( ) is an immutable priority and can't be written to.

Error message

{0} ({1}) is an immutable priority and can't be written to.

What it means

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.

Solutions

  1. Set the update's Priority to a writable priority such as UserPolicy instead of an immutable one
  2. Filter out updates whose Priority is in FeatureManager.ImmutablePriorities before calling SetFeatureConfigurations
  3. If replaying a saved configuration, rebuild each update with only user-writable fields and a user-writable priority

Example fix

// before
var update = new RTL_FEATURE_CONFIGURATION_UPDATE { FeatureId = id, Priority = RTL_FEATURE_CONFIGURATION_PRIORITY.OS }; // immutable
// after
var update = new RTL_FEATURE_CONFIGURATION_UPDATE { FeatureId = id, Priority = RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy, EnabledState = RTL_FEATURE_ENABLED_STATE.Enabled, UserPolicyPriorityCompatible = true };
Defensive patterns

Strategy: validation

Validate before calling

if (ViVe.Feature.FeatureManager.ImmutablePriorities.Contains(update.Priority))
    throw new InvalidOperationException($"Priority {update.Priority} is system-managed; use a writable priority such as UserPolicy.");

Type guard

static bool IsWritablePriority(RTL_FEATURE_CONFIGURATION_PRIORITY p) =>
    !ViVe.Feature.FeatureManager.ImmutablePriorities.Contains(p);

Try / catch

try
{
    ViVe.Feature.FeatureManager.SetFeatureConfigurations(updates, RTL_FEATURE_CONFIGURATION_TYPE.Runtime, ref stamp);
}
catch (ArgumentException ex) when (ex.Message.Contains("immutable priority"))
{
    // log and drop or rewrite the offending update
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of thebookisclosed/ViVe@3f8c6a3425 (2026-09-14). Data as JSON: /api/errors/2014195c0ff602ee. Report an issue: GitHub.

Appendix: source

Thrown at ViVe/FeatureManager.cs:94

            return config;
        }

        public static ulong QueryFeatureConfigurationChangeStamp()
        {
            return Ntdll.RtlQueryFeatureConfigurationChangeStamp();
        }

        public static int SetFeatureConfigurations(RTL_FEATURE_CONFIGURATION_UPDATE[] updates, RTL_FEATURE_CONFIGURATION_TYPE configurationType = RTL_FEATURE_CONFIGURATION_TYPE.Runtime)
        {
            ulong dummy = 0;
            return SetFeatureConfigurations(updates, configurationType, ref dummy);
        }

        public static int SetFeatureConfigurations(RTL_FEATURE_CONFIGURATION_UPDATE[] updates, RTL_FEATURE_CONFIGURATION_TYPE configurationType, ref ulong previousChangeStamp)
        {
            foreach (var update in updates)
                if (ImmutablePriorities.Contains(update.Priority))
                    throw new ArgumentException(string.Format("{0} ({1}) is an immutable priority and can't be written to.", update.Priority, (int)update.Priority));
                else if (update.Priority == RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy && !update.UserPolicyPriorityCompatible)
                    throw new ArgumentException("UserPolicy priority overrides do not support persisting properties other than EnabledState.");

            if (configurationType == RTL_FEATURE_CONFIGURATION_TYPE.Runtime)
                return Ntdll.RtlSetFeatureConfigurations(ref previousChangeStamp, RTL_FEATURE_CONFIGURATION_TYPE.Runtime, updates, updates.Length);
            else
                return SetFeatureConfigurationsInRegistry(updates, previousChangeStamp);
        }

        public static IntPtr RegisterFeatureConfigurationChangeNotification(FeatureConfigurationChangeCallback callback)
        {
            return RegisterFeatureConfigurationChangeNotification(callback, IntPtr.Zero);
        }

        public static IntPtr RegisterFeatureConfigurationChangeNotification(FeatureConfigurationChangeCallback callback, IntPtr context)
        {
            Ntdll.RtlRegisterFeatureConfigurationChangeNotification(callback, context, IntPtr.Zero, out IntPtr sub);
            return sub;

View on GitHub (pinned to 3f8c6a3425)