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
- Register an interaction service before building the host: builder.Services.AddSingleton<IInteractionService>(new ConsoleInteractionService(...)) or rely on the hosting layer's registration.
- Resolve IInteractionService from the service provider rather than passing a field that may be null.
- 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
- Register IInteractionService (or use the hosting layer's default registration) before building the host.
- Resolve the interaction service with GetRequiredService so a missing registration fails loudly with a clearer error.
- In test hosts, always provide a stub IInteractionService.
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
- Value cannot be null. (Parameter 'logger')
- Value cannot be null. (Parameter 'serviceProvider')
- Value cannot be null. (Parameter 'services')
- A QueueServiceClient could not be configured. Ensure valid…
- adminPassword
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)