thebookisclosed/ViVe · error · FeaturePropertyOverflowException

VariantPayloadKind must not be higher than 3.

Error message

VariantPayloadKind must not be higher than 3.

What it means

VariantPayloadKind in RTL_FEATURE_CONFIGURATION is a 2-bit field (bits 14-15 of CompactState) with only values 0-3 defined (None, and the payload kinds). Assigning a cast value above 3 would corrupt the packed state, so the setter throws FeaturePropertyOverflowException("VariantPayloadKind", 3).

Solutions

  1. Mask the raw value: (raw >> 14) & 0x3 before casting
  2. Only assign defined RTL_FEATURE_VARIANT_PAYLOAD_KIND members (0-3)
  3. Use VariantPayloadKind.None when no payload is intended

Example fix

// before
config.VariantPayloadKind = (RTL_FEATURE_VARIANT_PAYLOAD_KIND)rawDword;
// after
config.VariantPayloadKind = (RTL_FEATURE_VARIANT_PAYLOAD_KIND)((rawDword >> 14) & 0x3);
Defensive patterns

Strategy: validation

Validate before calling

uint k = (uint)kind;
if (k > 3) throw new ArgumentOutOfRangeException(nameof(kind), "VariantPayloadKind must be 0-3.");
config.VariantPayloadKind = (RTL_FEATURE_VARIANT_PAYLOAD_KIND)k;

Type guard

static bool IsValidVariantPayloadKind(uint v) => v <= 3;

Try / catch

try { config.VariantPayloadKind = kind; }
catch (FeaturePropertyOverflowException ex)
{
    // default to VariantPayloadKind.None or report decode failure
}

Prevention

When it happens

Trigger: Assigning config.VariantPayloadKind = (RTL_FEATURE_VARIANT_PAYLOAD_KIND)rawValue where rawValue > 3.

Common situations: Decoding native/registry data without isolating bits 14-15; confusion with the Variant field's 6-bit range; using sentinel values not defined by the enum.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at ViVe/NativeStructs.cs:115

            }
            set
            {
                if (value > 63)
                    throw new FeaturePropertyOverflowException("Variant", 63);
                CompactState = (CompactState & 0xFFFFC0FF) | (value << 8);
            }
        }

        public RTL_FEATURE_VARIANT_PAYLOAD_KIND VariantPayloadKind
        {
            get
            {
                return (RTL_FEATURE_VARIANT_PAYLOAD_KIND)((CompactState & 0xC000) >> 14);
            }
            set
            {
                if ((uint)value > 3)
                    throw new FeaturePropertyOverflowException("VariantPayloadKind", 3);
                CompactState = (CompactState & 0xFFFF3FFF) | ((uint)value << 14);
            }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS
    {
        public uint FeatureId;
        public ushort ReportingKind;
        public ushort ReportingOptions;
        public ulong ReportingTarget;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RTL_FEATURE_CONFIGURATION_UPDATE
    {
        public uint FeatureId;

View on GitHub (pinned to 3f8c6a3425)