{"record":{"id":"ef6a2f8b68d2ba30","repo":"microsoft/aspire","slug":"registered-service-descriptor-for-typeof-ihost-does-not","errorCode":null,"errorMessage":"Registered service descriptor for {typeof(IHost)} does not conform to any known pattern.","messagePattern":"Registered service descriptor for (.+?) does not conform to any known pattern\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Testing/DistributedApplicationFactory.cs","lineNumber":549,"sourceCode":"                // Ignore during disposal.\n            }\n        }\n    }\n\n    // Replaces the IHost registration with an InterceptedHost registration which delegates to the original registration.\n    private void InterceptHostCreation(DistributedApplicationBuilder applicationBuilder)\n    {\n        // Find the original IHost registration and remove it.\n        var hostDescriptor = applicationBuilder.Services.Single(s => s.ServiceType == typeof(IHost) && s.ServiceKey is null);\n        applicationBuilder.Services.Remove(hostDescriptor);\n\n        // Insert the registration, modified to be a keyed service keyed on this factory instance.\n        var interceptedDescriptor = hostDescriptor switch\n        {\n            { ImplementationFactory: { } factory } => ServiceDescriptor.KeyedSingleton<IHost>(this, (sp, _) => (IHost)factory(sp)),\n            { ImplementationInstance: { } instance } => ServiceDescriptor.KeyedSingleton<IHost>(this, (IHost)instance),\n            { ImplementationType: { } type } => ServiceDescriptor.KeyedSingleton(typeof(IHost), this, type),\n            _ => throw new InvalidOperationException($\"Registered service descriptor for {typeof(IHost)} does not conform to any known pattern.\")\n        };\n        applicationBuilder.Services.Add(interceptedDescriptor);\n\n        // Add a non-keyed registration which resolved the keyed registration, enabling interception.\n        applicationBuilder.Services.AddSingleton<IHost>(sp => new ObservedHost(sp.GetRequiredKeyedService<IHost>(this), this));\n    }\n\n    private sealed class ObservedHost(IHost innerHost, DistributedApplicationFactory appFactory) : IHost, IAsyncDisposable\n    {\n        private bool _disposing;\n\n        public IServiceProvider Services => innerHost.Services;\n\n        public void Dispose()\n        {\n            if (_disposing)\n            {\n                return;","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Testing/DistributedApplicationFactory.cs#L531-L567","documentation":"DistributedApplicationFactory intercepts the IHost registration that the inner test app adds, re-keying it on the factory instance so it can observe host creation. The IHost ServiceDescriptor must supply one of ImplementationFactory, ImplementationInstance, or ImplementationType; if it supplies none, the factory cannot re-key it and throws this error. This is an internal invariant violation: it means the hosting/test infrastructure changed its IHost registration shape.","triggerScenarios":"Calling CreateAsync/StartAsync on a DistributedApplicationFactory (or DistributedApplicationTesting.CreateAsync) when the application's IHost service descriptor in DI has no implementation factory, instance, or type — typically from custom test-host wiring or a mismatched Microsoft.Extensions.Hosting version replacing the standard registration.","commonSituations":"Custom test scaffolding that pre-registers IHost with an empty/odd descriptor; package version skew between Aspire.Hosting.Testing and Microsoft.Extensions.Hosting after upgrades; code that replaces or removes the default IHost registration before the factory builds.","solutions":["Check that the inner app's IHost descriptor is added by the standard HostBuilder pipeline, not by custom DI code.","Align Microsoft.Extensions.Hosting / Aspire.Hosting.Testing package versions across the test project.","Inspect builder.Services for IHost descriptors before creating the app and remove/replace non-standard registrations.","Report to Aspire if caused by an infrastructure change, since it indicates an unrecognized registration pattern."],"exampleFix":"// before (custom descriptor without implementation)\nbuilder.Services.Add(new ServiceDescriptor(typeof(IHost), (IHost)null!));\n// after (supply an implementation factory)\nbuilder.Services.Add(ServiceDescriptor.Singleton<IHost>(sp => sp.BuildHost()));","handlingStrategy":"try-catch","validationCode":"var descriptors = appBuilder.Services.Where(d => d.ServiceType == typeof(IHost)).ToList();\nif (descriptors.Any(d => d.ImplementationFactory is null && d.ImplementationInstance is null && d.ImplementationType is null))\n{\n    throw new InvalidOperationException(\"IHost descriptor has no implementation; DistributedApplicationFactory cannot intercept it.\");\n}","typeGuard":"static bool HasUsableIHostDescriptor(IServiceProvider sp) =>\n    sp.GetRequiredService<IServiceCollection>() is var s &&\n    s.Where(d => d.ServiceType == typeof(IHost)).All(d =>\n        d.ImplementationFactory is not null || d.ImplementationInstance is not null || d.ImplementationType is not null);","tryCatchPattern":"try\n{\n    var app = await DistributedApplicationTesting.CreateAsync<Program>();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not conform to any known pattern\"))\n{\n    // IHost registration was replaced by non-standard DI code; inspect builder.Services.\n}","preventionTips":["Do not replace or remove the standard IHost registration in test AppHosts.","Keep Aspire.Hosting.Testing and Microsoft.Extensions.Hosting packages on aligned versions.","Review custom DI code in AppHost Program.cs that touches typeof(IHost)."],"tags":["dependency-injection","testing","host-builder"],"backgroundTag":"internal-invariant-violation","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"}