microsoft/aspire · error · DistributedApplicationException

ResourceReadyEvent was published for the

Error message

ResourceReadyEvent was published for the '{resource.Name}' resource but the connection string was null.

What it means

In AddMySql, the ResourceReadyEvent handler uses the connection string captured earlier to open a MySqlConnection and create requested databases. If the captured connectionString is still null when the resource reports ready, the earlier ConnectionStringAvailableEvent never delivered a value, so this DistributedApplicationException is thrown.

Solutions

  1. Verify the resource uses the standard Aspire MySQL resource lifecycle so both events are published in order.
  2. Do not suppress or replace the ConnectionStringAvailableEvent subscription when customizing the builder.
  3. Inspect custom eventing code that may publish ResourceReadyEvent without first resolving the connection string.
Defensive patterns

Strategy: try-catch

Try / catch

try { /* use resource */ } catch (DistributedApplicationException ex) { logger.LogError(ex, "MySQL connection string was null on ResourceReadyEvent"); throw; }

Prevention

When it happens

Trigger: ResourceReadyEvent fires for the MySQL resource while the closure variable connectionString is null — i.e. ConnectionStringAvailableEvent never ran or ran with a null result before readiness.

Common situations: Resource becomes ready without the connection-string-available event having fired (custom lifecycle, eventing misconfiguration); ordering anomalies in custom resource models that skip standard event publication.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/6133e828b68422bd. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.MySql/MySqlBuilderExtensions.cs:61

        var resource = new MySqlServerResource(name, passwordParameter);

        string? connectionString = null;

        builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(resource, async (@event, ct) =>
        {
            connectionString = await resource.ConnectionStringExpression.GetValueAsync(ct).ConfigureAwait(false);

            if (connectionString == null)
            {
                throw new DistributedApplicationException($"ConnectionStringAvailableEvent was published for the '{resource.Name}' resource but the connection string was null.");
            }
        });

        builder.Eventing.Subscribe<ResourceReadyEvent>(resource, async (@event, ct) =>
        {
            if (connectionString is null)
            {
                throw new DistributedApplicationException($"ResourceReadyEvent was published for the '{resource.Name}' resource but the connection string was null.");
            }

            using var sqlConnection = new MySqlConnection(connectionString);
            await sqlConnection.OpenAsync(ct).ConfigureAwait(false);

            if (sqlConnection.State != System.Data.ConnectionState.Open)
            {
                throw new InvalidOperationException($"Could not open connection to '{resource.Name}'");
            }

            foreach (var sqlDatabase in resource.DatabaseResources)
            {
                await CreateDatabaseAsync(sqlConnection, sqlDatabase, @event.Services, ct).ConfigureAwait(false);
            }
        });

        var healthCheckKey = $"{name}_check";
        builder.Services.AddHealthChecks().AddMySql(sp => connectionString ?? throw new InvalidOperationException("Connection string is unavailable"), name: healthCheckKey);

View on GitHub (pinned to 25830f84bd)