{"record":{"id":"4da741cfc71de237","repo":"microsoft/aspire","slug":"connectionstringavailableevent-was-published-for-the-name-4da741","errorCode":null,"errorMessage":"ConnectionStringAvailableEvent was published for the '{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":"error","filePath":"src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs","lineNumber":146,"sourceCode":"\n        builder.Resource.AddDatabase(sqlServerDatabase);\n\n        string? connectionString = null;\n\n        var healthCheckKey = $\"{name}_check\";\n        builder.ApplicationBuilder.Services.AddHealthChecks().AddSqlServer(sp => connectionString ?? throw new InvalidOperationException(\"Connection string is unavailable\"), name: healthCheckKey);\n\n        return builder.ApplicationBuilder\n            .AddResource(sqlServerDatabase)\n            .WithIconName(\"Database\")\n            .WithHealthCheck(healthCheckKey)\n            .OnConnectionStringAvailable(async (sqlServerDatabase, @event, ct) =>\n            {\n                connectionString = await sqlServerDatabase.ConnectionStringExpression.GetValueAsync(ct).ConfigureAwait(false);\n\n                if (connectionString == null)\n                {\n                    throw new DistributedApplicationException($\"ConnectionStringAvailableEvent was published for the '{name}' resource but the connection string was null.\");\n                }\n            });\n    }\n\n    /// <summary>\n    /// Adds a named volume for the data folder to a SQL Server resource.\n    /// </summary>\n    /// <param name=\"builder\">The resource builder.</param>\n    /// <param name=\"name\">The name of the volume. Defaults to an auto-generated name based on the application and resource names.</param>\n    /// <param name=\"isReadOnly\">A flag that indicates if this is a read-only volume.</param>\n    /// <returns>The <see cref=\"IResourceBuilder{T}\"/>.</returns>\n    /// <ats-returns>The resource builder.</ats-returns>\n    [AspireExport]\n    public static IResourceBuilder<SqlServerServerResource> WithDataVolume(this IResourceBuilder<SqlServerServerResource> builder, string? name = null, bool isReadOnly = false)\n    {\n        ArgumentNullException.ThrowIfNull(builder);\n\n        return builder.WithVolume(name ?? VolumeNameGenerator.Generate(builder, \"data\"), \"/var/opt/mssql\", isReadOnly);","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.SqlServer/SqlServerBuilderExtensions.cs#L128-L164","documentation":"The OnConnectionStringAvailable callback in AddDatabase resolves the resource's ConnectionStringExpression and asserts the result is non-null. This DistributedApplicationException indicates the event fired but the connection string expression still evaluated to null — an internal inconsistency in the resource's connection-string pipeline.","triggerScenarios":"ConnectionStringAvailableEvent is published for the SqlServerDatabaseResource but GetValueAsync on its ConnectionStringExpression returns null, e.g. the parent SQL Server resource's endpoint/reference configuration was mutated or the database resource was constructed without a valid parent reference.","commonSituations":"Custom resource transformations removing or replacing the parent reference or endpoint; building a database resource manually without AddSqlServer; version mismatch between Aspire packages handling connection string events differently.","solutions":["Ensure the database resource is created via AddSqlServer(...).AddDatabase(...) and not constructed manually","Check for custom callbacks (OnResourceModified, transformations) that might clear or replace the connection string or parent reference","Verify all Aspire.Hosting.* packages are on the same version","Log the resource's ConnectionStringExpression earlier in the lifecycle to see when it becomes null"],"exampleFix":"// before\nvar db = new SqlServerDatabaseResource(\"db\", cs => null, sqlServerResource);\n// after\nvar db = builder.AddSqlServer(\"sql\").AddDatabase(\"db\");","handlingStrategy":"try-catch","validationCode":"var cs = await dbResource.ConnectionStringExpression.GetValueAsync(ct);\nif (cs is null)\n{\n    throw new InvalidOperationException($\"'{dbResource.Name}' has no connection string; check parent resource config\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    connectionString = await dbResource.ConnectionStringExpression.GetValueAsync(ct);\n}\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"ConnectionStringAvailableEvent\"))\n{\n    logger.LogError(ex, \"Connection string pipeline broken for {Resource}\", dbResource.Name);\n    throw;\n}","preventionTips":["Create database resources only via AddSqlServer(...).AddDatabase(...)","Avoid resource transformations that strip parent references or endpoints","Keep all Aspire.Hosting.* packages on the same version","Log ConnectionStringExpression values early in the lifecycle to catch nulls before the event"],"tags":["sqlserver","connection-string","invariant","aspire"],"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"}