thebookisclosed/ViVe · error · ArgumentException
UserPolicy priority overrides do not support persisting…
Error message
UserPolicy priority overrides do not support persisting properties other than EnabledState.
What it means
When an update targets the UserPolicy priority, ViVe enforces the OS constraint that only the EnabledState property may be persisted at that level; any other property (Variant, VariantPayloadKind, etc.) makes the update invalid and it throws ArgumentException before calling the native API. This mirrors a check the Windows kernel/ntdll performs, surfaced early as a .NET exception.
Solutions
- Set update.UserPolicyPriorityCompatible = true and ensure only EnabledState is meaningful, or
- Move Variant/VariantPayloadKind and other properties onto an update with a non-UserPolicy priority
- Split the change into two updates: one UserPolicy update carrying only EnabledState, plus a separate update at another writable priority for other properties
Example fix
// before
var u = new RTL_FEATURE_CONFIGURATION_UPDATE { FeatureId = id, Priority = RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy, Variant = 3 }; // incompatible
// after
var u = 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 (update.Priority == RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy && !update.UserPolicyPriorityCompatible)
throw new InvalidOperationException("UserPolicy updates may only persist EnabledState; set UserPolicyPriorityCompatible or move other properties to another priority."); Type guard
static bool IsUserPolicyCompatible(RTL_FEATURE_CONFIGURATION_UPDATE u) =>
u.Priority != RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy || u.UserPolicyPriorityCompatible; Try / catch
try
{
ViVe.Feature.FeatureManager.SetFeatureConfigurations(updates, configType, ref stamp);
}
catch (ArgumentException ex) when (ex.Message.Contains("UserPolicy"))
{
// split the update or set UserPolicyPriorityCompatible and retry
} Prevention
- Set UserPolicyPriorityCompatible = true when using UserPolicy updates with only EnabledState
- Keep Variant/VariantPayloadKind changes in separate updates at other priorities
- Reuse of read-back update structs: always re-check the UserPolicy constraint
When it happens
Trigger: Calling SetFeatureConfigurations with an update whose Priority == RTL_FEATURE_CONFIGURATION_PRIORITY.UserPolicy and whose UserPolicyPriorityCompatible flag is false, meaning non-EnabledState properties are set and would be persisted.
Common situations: Trying to persist variant/payload data alongside a user-policy override; reusing a runtime-priority update struct and merely switching Priority to UserPolicy without clearing other properties or setting UserPolicyPriorityCompatible.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- ( ) is an immutable priority and can't be written to.
- Priority must not be higher than 15.
- EnabledState must not be higher than 2.
- Variant must not be higher than 63.
- VariantPayloadKind must not be higher than 3.
AI-assisted analysis of thebookisclosed/ViVe@3f8c6a3425 (2026-09-14).
Data as JSON: /api/errors/68f2f8a50e11cdd9.
Report an issue: GitHub.
Appendix: source
Thrown at ViVe/FeatureManager.cs:96
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)