microsoft/aspire · error · ArgumentNullException

Value cannot be null. (Parameter 'interactionService')

Error message

Value cannot be null. (Parameter 'interactionService')

What it means

RequiredCommandValidator uses IInteractionService to prompt users when a required command fails validation (e.g. offering to install it). The constructor null-guards this dependency, so a null interactionService throws ArgumentNullException with parameter name 'interactionService'. Without it the validator could not surface validation failures to the dashboard or console.

Solutions

  1. Register an interaction service before building the host: builder.Services.AddSingleton<IInteractionService>(new ConsoleInteractionService(...)) or rely on the hosting layer's registration.
  2. Resolve IInteractionService from the service provider rather than passing a field that may be null.
  3. In tests, provide a stub IInteractionService implementation that records/ignores interactions.

Example fix

// before
var validator = new RequiredCommandValidator(sp, interactionService!, logger); // interactionService null
// after
builder.Services.AddSingleton<IInteractionService, ConsoleInteractionService>();
var validator = new RequiredCommandValidator(sp, sp.GetRequiredService<IInteractionService>(), logger);
Defensive patterns

Strategy: validation

Validate before calling

if (interactionService is null)
{
    throw new InvalidOperationException("Register IInteractionService in DI before constructing RequiredCommandValidator.");
}

Type guard

bool HasInteractionService(IServiceProvider sp) => sp.GetService<IInteractionService>() is not null;

Try / catch

try
{
    var validator = new RequiredCommandValidator(serviceProvider, interactionService, logger);
}
catch (ArgumentNullException ex) when (ex.ParamName == "interactionService")
{
    interactionService = serviceProvider.GetRequiredService<IInteractionService>();
}

Prevention

When it happens

Trigger: new RequiredCommandValidator(serviceProvider, null!, logger) — constructing the validator with no interaction service; a DI registration that maps IInteractionService to null (e.g. missing registration resolved with a null default).

Common situations: Headless/test hosts that skip registering IInteractionService; manual construction in custom tooling where the interaction service was not yet initialized at validator creation time.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/71c7c711569eb0bf. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/ApplicationModel/RequiredCommandValidator.cs:32

/// Default implementation of <see cref="IRequiredCommandValidator"/> that validates commands
/// are available on the local machine PATH and coalesces validations per command.
/// </summary>
internal sealed class RequiredCommandValidator : IRequiredCommandValidator, IDisposable
{
    private readonly IServiceProvider _serviceProvider;
    private readonly IInteractionService _interactionService;
    private readonly ILogger<RequiredCommandValidator> _logger;

    // Track validation state per command/callback pair to coalesce notifications and validation work.
    private readonly ConcurrentDictionary<CommandValidationCacheKey, CommandValidationState> _commandStates = new();

    public RequiredCommandValidator(
        IServiceProvider serviceProvider,
        IInteractionService interactionService,
        ILogger<RequiredCommandValidator> logger)
    {
        _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
        _interactionService = interactionService ?? throw new ArgumentNullException(nameof(interactionService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// Disposes the command validation states, releasing their semaphores.
    /// </summary>
    public void Dispose()
    {
        foreach (var state in _commandStates.Values)
        {
            state.Dispose();
        }
        _commandStates.Clear();
    }

    /// <inheritdoc />
    public async Task<RequiredCommandValidationResult> ValidateAsync(
        IResource resource,

View on GitHub (pinned to 25830f84bd)