microsoft/aspire · error · ArgumentNullException

Value cannot be null. (Parameter 'logger')

Error message

Value cannot be null. (Parameter 'logger')

What it means

RequiredCommandValidator logs validation activity and failures through ILogger<RequiredCommandValidator>. Its constructor null-guards the logger, so passing null throws ArgumentNullException with parameter name 'logger'. The logger is required for diagnostics while running and disposing command validation states.

Solutions

  1. Pass a typed logger: sp.GetRequiredService<ILogger<RequiredCommandValidator>>() after registering logging (builder.Services.AddLogging() / AddAspireLogging defaults).
  2. Use NullLogger<RequiredCommandValidator>.Instance when you intentionally want no-op logging (e.g. tests).
  3. Prefer constructing the validator through DI so the logger is injected automatically.

Example fix

// before
var validator = new RequiredCommandValidator(sp, interactionService, null!);
// after
var validator = new RequiredCommandValidator(sp, interactionService,
    sp.GetRequiredService<ILogger<RequiredCommandValidator>>());
Defensive patterns

Strategy: validation

Validate before calling

if (logger is null)
{
    throw new InvalidOperationException("Provide ILogger<RequiredCommandValidator>; use NullLogger<T>.Instance for no-op logging.");
}

Type guard

bool CanBuildValidator(IServiceProvider? sp, IInteractionService? isvc, ILogger? logger) => sp is not null && isvc is not null && logger is not null;

Try / catch

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

Prevention

When it happens

Trigger: new RequiredCommandValidator(serviceProvider, interactionService, null!) — constructing the validator without a logger; resolving ILogger<RequiredCommandValidator> from a container where logging services were never registered.

Common situations: Unit tests that build the validator manually without AddLogging; minimal hosts constructed without logging infrastructure, leaving the typed logger unresolvable and passed as null.

Related errors


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

Appendix: source

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

/// 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,
        RequiredCommandAnnotation annotation,

View on GitHub (pinned to 25830f84bd)