dotnet/reactive · error · InvalidOperationException

RxUiFrameworkPackages must not be null.

Error message

RxUiFrameworkPackages  must not be null.

What it means

Same guard as the RxMainPackage check, applied to RxUiFrameworkPackages: it must be a non-null string[]. Spectre.Console would never bind null, so null signals use outside the supported command pipeline. Note the message contains a double space ('RxUiFrameworkPackages must not be null.') due to a typo in the source.

Solutions

  1. Assign RxUiFrameworkPackages to a non-null string[] of '<PackageId>,<Version>' entries before validating
  2. Use the Spectre.Console command pipeline so both properties are always bound
  3. Search for the double-space in the message if you are matching it in tests — the literal text has two spaces

Example fix

// before
var settings = new RxSourceSettings { RxMainPackage = "System.Reactive,6.0.1" };
// after
var settings = new RxSourceSettings { RxMainPackage = "System.Reactive,6.0.1", RxUiFrameworkPackages = new[] { "Rx.WPF,1.0.0", "Rx.Maui,1.0.0" } };
Defensive patterns

Strategy: validation

Validate before calling

if (settings.RxUiFrameworkPackages is not string[] pkgs || pkgs.Length == 0) { throw new ArgumentException("RxUiFrameworkPackages must be a non-empty string[]"); }

Type guard

bool usable = settings.RxUiFrameworkPackages is string[] p && p.All(x => x.Contains(','));

Try / catch

try { settings.Validate(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("RxUiFrameworkPackages")) { /* supply the packages array */ }

Prevention

When it happens

Trigger: Calling Validate() on an RxSourceSettings where RxMainPackage is set but RxUiFrameworkPackages was never assigned (is null or not a string[]), outside Spectre.Console binding.

Common situations: Manual construction in tests or tooling that sets only RxMainPackage; refactoring that renamed/removed the RxUiFrameworkPackages assignment.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/50acdfba8a104a8c. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Test/Gauntlet/RxGauntlet.Common/CommandLine/RxSourceSettings.cs:105

    /// </summary>
    /// <returns>A value indicating whether the settings are valid.</returns>
    /// <exception cref="InvalidOperationException">
    /// Thrown if this object's properties are set in a way that we do not expect from Spectre Console CLI.
    /// </exception>
    public override ValidationResult Validate()
    {
        // Spectre Console will never make the following properties null, so this can only mean that we're being used
        // in an unsupported way (probably not via Spectre.Console) so we throw instead of reporting a validation
        // failure.

        if (RxMainPackage is not string rxMainPackage)
        {
            throw new InvalidOperationException($"{nameof(RxMainPackage)} must not be null.");
        }

        if (RxUiFrameworkPackages is not string[] rxUiPackages)
        {
            throw new InvalidOperationException($"{nameof(RxUiFrameworkPackages)}  must not be null.");
        }

        if (!PackageIdAndVersion.TryParse(rxMainPackage, out _parsedRxMainPackage))
        {
            return ValidationResult.Error($"Invalid package specification: {RxMainPackage}. Must be <PackageId>,<Version>");
        }

        if (RxLegacyPackage is string rxLegacyPackage &&
            !PackageIdAndVersion.TryParse(rxLegacyPackage, out _parsedRxLegacyPackage))
        {
            return ValidationResult.Error($"Invalid package specification: {rxLegacyPackage}. Must be <PackageId>,<Version>");
        }

        HashSet<string> uiPackageIdsSeen = new(capacity: rxUiPackages.Length);
        var uiPackageIdsAndVersions = new PackageIdAndVersion[rxUiPackages.Length];
        for (var i = 0; i < rxUiPackages.Length; i++)
        {
            if (!PackageIdAndVersion.TryParse(rxUiPackages[i], out var packageIdAndVersion))

View on GitHub (pinned to 94b5d5ab91)