{"record":{"id":"4b523863abb75fa6","repo":"microsoft/aspire","slug":"value-cannot-be-null-parameter-logger-containerruntimebase","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'logger')","messagePattern":"Value cannot be null\\. \\(Parameter 'logger'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Publishing/ContainerRuntimeBase.cs","lineNumber":28,"sourceCode":"using System.Text.Json.Serialization;\nusing Aspire.Hosting.ApplicationModel;\nusing Aspire.Hosting.Dcp.Process;\nusing Microsoft.Extensions.Logging;\n\nnamespace Aspire.Hosting.Publishing;\n\n/// <summary>\n/// Base class for container runtime implementations that provides common process execution,\n/// logging, and error handling patterns.\n/// </summary>\ninternal abstract class ContainerRuntimeBase<TLogger> : IContainerRuntime where TLogger : class\n{\n    private readonly ILogger<TLogger> _logger;\n    private readonly IProcessRunner _processRunner;\n\n    protected ContainerRuntimeBase(ILogger<TLogger> logger, IProcessRunner processRunner)\n    {\n        _logger = logger ?? throw new ArgumentNullException(nameof(logger));\n        _processRunner = processRunner ?? throw new ArgumentNullException(nameof(processRunner));\n    }\n\n    /// <summary>\n    /// Gets the logger instance for use in derived classes.\n    /// </summary>\n    protected ILogger<TLogger> Logger => _logger;\n\n    /// <summary>\n    /// Gets the process runner used for container runtime commands.\n    /// </summary>\n    protected IProcessRunner ProcessRunner => _processRunner;\n\n    /// <summary>\n    /// Gets the name of the container runtime executable (e.g., \"docker\", \"podman\").\n    /// </summary>\n    protected abstract string RuntimeExecutable { get; }\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Publishing/ContainerRuntimeBase.cs#L10-L46","documentation":"The ContainerRuntimeBase protected constructor guards its ILogger<TLogger> dependency with ArgumentNullException. A null logger means the runtime implementation (Docker/Podman) was constructed without required infrastructure, so it cannot log container operations.","triggerScenarios":"Constructing a concrete ContainerRuntimeBase subclass (e.g. DockerRuntime) passing null for the logger parameter.","commonSituations":"Manual instantiation in tests with null! placeholders; DI container not registering ILogger<T> for the runtime type; custom runtime subclass forgetting to resolve the logger from the service provider.","solutions":["Register and resolve ILogger<TLogger> from DI when constructing the runtime.","In tests, use NullLogger<TLogger>.Instance instead of null.","Fix the composition root so the runtime is created through the service provider."],"exampleFix":"// before\nnew DockerRuntime(null!, processRunner);\n// after\nnew DockerRuntime(NullLogger<DockerRuntime>.Instance, processRunner);","handlingStrategy":"type-guard","validationCode":"if (logger is null) throw new InvalidOperationException(\"ContainerRuntimeBase requires a non-null ILogger<TLogger>\");","typeGuard":"static bool CanCreateRuntime(ILogger<DockerRuntime>? logger, IProcessRunner? runner) => logger is not null && runner is not null;","tryCatchPattern":"try { runtime = new DockerRuntime(logger, processRunner); }\ncatch (ArgumentNullException ex) when (ex.ParamName is \"logger\" or \"processRunner\")\n{\n    logger ??= NullLogger<DockerRuntime>.Instance;\n    runtime = new DockerRuntime(logger, processRunner!);\n}","preventionTips":["Always construct runtimes via DI so ILogger<T> is injected.","Use NullLogger<T>.Instance in tests, never null.","Add logger diagnostics Disable to fail fast at startup on missing registrations."],"tags":["logging","dependency-injection","constructor"],"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"}