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
- Pass a non-null IServiceProvider, typically the app builder's or resource's service provider (builder.ServiceProvider / executionContext.ServiceProvider).
- If obtaining the provider from DI, resolve it via ActivatorUtilities or host.Services instead of passing a field that may be null.
- 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
- Always source the IServiceProvider from host.Services / app.Services, never from a nullable field.
- Construct validation contexts inside the hosting pipeline where DI is already initialized.
- Enable nullable reference types so null providers are flagged at compile time.
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
- Value cannot be null. (Parameter 'serviceProvider')
- Value cannot be null. (Parameter 'interactionService')
- Value cannot be null. (Parameter 'logger')
- -32602
- A QueueServiceClient could not be configured. Ensure valid…
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)