microsoft/aspire · error · ArgumentNullException

Value cannot be null. (Parameter 'services')

Error message

Value cannot be null. (Parameter 'services')

What it means

RequiredCommandValidationContext bundles the data a resource's ValidateRequiredCommand callback needs: the resolved executable path, an IServiceProvider for application services, and a CancellationToken. The constructor null-guards the services argument and throws ArgumentNullException when a null IServiceProvider is passed. The library requires a real service provider so validation callbacks can resolve application services during command validation.

Solutions

  1. Pass a non-null IServiceProvider, typically the app builder's or resource's service provider (builder.ServiceProvider / executionContext.ServiceProvider).
  2. If obtaining the provider from DI, resolve it via ActivatorUtilities or host.Services instead of passing a field that may be null.
  3. In unit tests, supply a minimal provider such as new ServiceCollection().BuildServiceProvider().

Example fix

// before
var ctx = new RequiredCommandValidationContext(resolvedPath, services!, ct);
// after
if (services is null)
{
    services = app.Services; // or another guaranteed non-null provider
}
var ctx = new RequiredCommandValidationContext(resolvedPath, services, ct);
Defensive patterns

Strategy: validation

Validate before calling

if (services is null)
{
    throw new InvalidOperationException("RequiredCommandValidationContext requires a non-null IServiceProvider; resolve it from the host or app builder first.");
}

Type guard

bool IsValidContext(RequiredCommandValidationContext ctx) => ctx is not null && ctx.Services is not null;

Try / catch

try
{
    var ctx = new RequiredCommandValidationContext(resolvedPath, services, ct);
}
catch (ArgumentNullException ex) when (ex.ParamName == "services")
{
    logger.LogError(ex, "Service provider was null when building validation context");
}

Prevention

When it happens

Trigger: Constructing RequiredCommandValidationContext directly with services: null, e.g. new RequiredCommandValidationContext(resolvedPath, null!, cancellationToken). The resolvedPath argument is also guarded, but this specific message fires only for the services parameter.

Common situations: Custom tooling or tests that build validation contexts manually instead of receiving them from the host; a DI container that failed to initialize and supplied null; refactoring that renamed a variable holding IServiceProvider so a different (null) value is passed.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationContext.cs:26

/// <summary>
/// Provides context for validating a required command.
/// </summary>
/// <param name="resolvedPath">The resolved full path to the command executable.</param>
/// <param name="services">The service provider for accessing application services.</param>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the validation.</param>
[Experimental("ASPIRECOMMAND001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[AspireExport(ExposeProperties = true, ExposeMethods = true)]
public sealed class RequiredCommandValidationContext(string resolvedPath, IServiceProvider services, CancellationToken cancellationToken)
{
    /// <summary>
    /// Gets the resolved full path to the command executable.
    /// </summary>
    public string ResolvedPath { get; } = resolvedPath ?? throw new ArgumentNullException(nameof(resolvedPath));

    /// <summary>
    /// Gets the service provider for accessing application services.
    /// </summary>
    public IServiceProvider Services { get; } = services ?? throw new ArgumentNullException(nameof(services));

    /// <summary>
    /// Gets a cancellation token that can be used to cancel the validation.
    /// </summary>
    public CancellationToken CancellationToken { get; } = cancellationToken;

    /// <summary>
    /// Creates a successful validation result.
    /// </summary>
    /// <returns>A <see cref="RequiredCommandValidationResult"/> indicating the command is valid.</returns>
    public RequiredCommandValidationResult Success() => RequiredCommandValidationResult.Success();

    /// <summary>
    /// Creates a failed validation result with the specified message.
    /// </summary>
    /// <param name="validationMessage">A message describing why validation failed.</param>
    /// <returns>A <see cref="RequiredCommandValidationResult"/> indicating the command is invalid.</returns>
    public RequiredCommandValidationResult Failure(string validationMessage) => RequiredCommandValidationResult.Failure(validationMessage);

View on GitHub (pinned to 25830f84bd)