{"record":{"id":"15533732657e17bc","repo":"microsoft/aspire","slug":"value-cannot-be-null-parameter-services","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'services')","messagePattern":"Value cannot be null\\. \\(Parameter 'services'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationContext.cs","lineNumber":26,"sourceCode":"/// <summary>\n/// Provides context for validating a required command.\n/// </summary>\n/// <param name=\"resolvedPath\">The resolved full path to the command executable.</param>\n/// <param name=\"services\">The service provider for accessing application services.</param>\n/// <param name=\"cancellationToken\">A cancellation token that can be used to cancel the validation.</param>\n[Experimental(\"ASPIRECOMMAND001\", UrlFormat = \"https://aka.ms/aspire/diagnostics/{0}\")]\n[AspireExport(ExposeProperties = true, ExposeMethods = true)]\npublic sealed class RequiredCommandValidationContext(string resolvedPath, IServiceProvider services, CancellationToken cancellationToken)\n{\n    /// <summary>\n    /// Gets the resolved full path to the command executable.\n    /// </summary>\n    public string ResolvedPath { get; } = resolvedPath ?? throw new ArgumentNullException(nameof(resolvedPath));\n\n    /// <summary>\n    /// Gets the service provider for accessing application services.\n    /// </summary>\n    public IServiceProvider Services { get; } = services ?? throw new ArgumentNullException(nameof(services));\n\n    /// <summary>\n    /// Gets a cancellation token that can be used to cancel the validation.\n    /// </summary>\n    public CancellationToken CancellationToken { get; } = cancellationToken;\n\n    /// <summary>\n    /// Creates a successful validation result.\n    /// </summary>\n    /// <returns>A <see cref=\"RequiredCommandValidationResult\"/> indicating the command is valid.</returns>\n    public RequiredCommandValidationResult Success() => RequiredCommandValidationResult.Success();\n\n    /// <summary>\n    /// Creates a failed validation result with the specified message.\n    /// </summary>\n    /// <param name=\"validationMessage\">A message describing why validation failed.</param>\n    /// <returns>A <see cref=\"RequiredCommandValidationResult\"/> indicating the command is invalid.</returns>\n    public RequiredCommandValidationResult Failure(string validationMessage) => RequiredCommandValidationResult.Failure(validationMessage);","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationContext.cs#L8-L44","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()."],"exampleFix":"// before\nvar ctx = new RequiredCommandValidationContext(resolvedPath, services!, ct);\n// after\nif (services is null)\n{\n    services = app.Services; // or another guaranteed non-null provider\n}\nvar ctx = new RequiredCommandValidationContext(resolvedPath, services, ct);","handlingStrategy":"validation","validationCode":"if (services is null)\n{\n    throw new InvalidOperationException(\"RequiredCommandValidationContext requires a non-null IServiceProvider; resolve it from the host or app builder first.\");\n}","typeGuard":"bool IsValidContext(RequiredCommandValidationContext ctx) => ctx is not null && ctx.Services is not null;","tryCatchPattern":"try\n{\n    var ctx = new RequiredCommandValidationContext(resolvedPath, services, ct);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"services\")\n{\n    logger.LogError(ex, \"Service provider was null when building validation context\");\n}","preventionTips":["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."],"tags":["null-argument","dependency-injection","validation"],"backgroundTag":"null-argument","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}