{"record":{"id":"a8c6fa0f1bb3f30b","repo":"microsoft/aspire","slug":"connectionstringavailableevent-was-published-for-the-nats","errorCode":null,"errorMessage":"ConnectionStringAvailableEvent was published for the '{nats.Name}' resource but the connection string was null.","messagePattern":"ConnectionStringAvailableEvent was published for the '(.+?)' resource but the connection string was null\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"critical","filePath":"src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs","lineNumber":67,"sourceCode":"    /// <remarks>This overload is not available in polyglot app hosts. Use <see cref=\"AddNatsForPolyglot\"/> instead.</remarks>\n    [AspireExportIgnore(Reason = \"Use the dedicated polyglot overload instead.\")]\n    public static IResourceBuilder<NatsServerResource> AddNats(this IDistributedApplicationBuilder builder, [ResourceName] string name, int? port = null,\n        IResourceBuilder<ParameterResource>? userName = null,\n        IResourceBuilder<ParameterResource>? password = null)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n        ArgumentException.ThrowIfNullOrEmpty(name);\n\n        var passwordParameter = password?.Resource ?? ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(builder, $\"{name}-password\", special: false);\n\n        var nats = new NatsServerResource(name, userName?.Resource, passwordParameter);\n\n        NatsConnection? natsConnection = null;\n\n        builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(nats, async (@event, ct) =>\n        {\n            var connectionString = await nats.ConnectionStringExpression.GetValueAsync(ct).ConfigureAwait(false)\n            ?? throw new DistributedApplicationException($\"ConnectionStringAvailableEvent was published for the '{nats.Name}' resource but the connection string was null.\");\n\n            var options = NatsOpts.Default with\n            {\n                LoggerFactory = @event.Services.GetRequiredService<ILoggerFactory>(),\n            };\n\n            options = options with\n            {\n                Url = connectionString,\n                AuthOpts = new()\n                {\n                    Username = await nats.UserNameReference.GetValueAsync(ct).ConfigureAwait(false),\n                    Password = await nats.PasswordParameter!.GetValueAsync(ct).ConfigureAwait(false),\n                }\n            };\n\n            natsConnection = new NatsConnection(options);\n        });","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Nats/NatsBuilderExtensions.cs#L49-L85","documentation":"AddNats subscribes to ConnectionStringAvailableEvent for the NATS resource and evaluates the resource's ConnectionStringExpression when it fires. If the expression evaluates to null, this DistributedApplicationException is thrown, because the event contract guarantees a connection string should exist by that point. It is an internal invariant failure: the resource was announced as ready for connection but produced no value.","triggerScenarios":"A ConnectionStringAvailableEvent is published for the NatsConnection resource but nats.ConnectionStringExpression.GetValueAsync returns null — e.g. the underlying parameter or endpoint reference backing the connection string is unconfigured or misconfigured when AddNats sets up its client callback.","commonSituations":"Missing or misnamed configuration/parameter that the NATS connection string expression depends on; custom builds of the resource that removed the endpoint or host reference; running the AppHost in a context where required inputs were not supplied before the event fired.","solutions":["Ensure the NATS resource's connection string inputs (host/endpoint/parameters) are configured in appsettings.json or Parameters before running the AppHost.","If using a custom NATS resource or WithConnectionString override, verify the expression never returns null and throws a clearer error earlier.","Check that ConnectionStringAvailableEvent is not being published manually or prematurely for this resource."],"exampleFix":"// before\nvar nats = builder.AddNats(\"nats\");\n// after — ensure required parameter exists\nvar host = builder.AddParameter(\"nats-host\");\nvar nats = builder.AddNats(\"nats\");","handlingStrategy":"validation","validationCode":"// Ensure NATS inputs exist before running\nif (builder.Configuration[\"Parameters:nats-host\"] is null &&\n    Environment.GetEnvironmentVariable(\"NATS_HOST\") is null)\n{\n    throw new InvalidOperationException(\"NATS host configuration missing; connection string will resolve to null.\");\n}","typeGuard":null,"tryCatchPattern":"try { await nats.ConnectionStringExpression.GetValueAsync(ct); } catch (DistributedApplicationException ex) { logger.LogError(ex, \"NATS connection string invariant broken\"); throw; }","preventionTips":["Use default AddNats wiring; do not override the connection string expression without guaranteeing a value","Keep required parameters in user secrets/appsettings for every environment","Never publish ConnectionStringAvailableEvent manually"],"tags":["aspire","nats","connection-string","eventing"],"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"}