microsoft/aspire · error · InvalidOperationException

Unexpected connection string type

Error message

Unexpected connection string type: {connectionStringAnnotation.ConnectionString.GetType().Name}

What it means

DurableTaskSchedulerResource.CreateConnectionString resolves the connection string stored in DurableTaskSchedulerConnectionStringAnnotation. The stored value must be a string or ParameterResource; any other type indicates an internal misuse of the annotation, so an InvalidOperationException naming the type is thrown while building ConnectionStringExpression.

Solutions

  1. Configure the scheduler only through the supported APIs: RunAsEmulator() or RunAsExisting(string | IResourceBuilder<ParameterResource>).
  2. Fix the code that constructs DurableTaskSchedulerConnectionStringAnnotation to store a string or ParameterResource.
  3. Update integration packages so the annotation producer and consumer agree on the stored type.

Example fix

// before
annotation = new DurableTaskSchedulerConnectionStringAnnotation(expressionObject); // wrong type

// after
var connParam = builder.AddParameter("scheduler-conn");
schedulerBuilder.RunAsExisting(connParam); // stores ParameterResource
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is not string and not ParameterResource) throw new InvalidOperationException("DurableTaskSchedulerConnectionStringAnnotation requires string or ParameterResource.");

Type guard

static bool IsValidConnectionStringAnnotation(object? v) => v is string or ParameterResource;

Try / catch

try { var expr = scheduler.ConnectionStringExpression; } catch (InvalidOperationException ex) when (ex.Message.StartsWith("Unexpected connection string type")) { /* fix the code storing the annotation */ }

Prevention

When it happens

Trigger: Reading ConnectionStringExpression on a scheduler resource whose connection-string annotation was populated by custom/incorrect code with an unsupported type (e.g., a ReferenceExpression or IResourceBuilder).

Common situations: Custom Durable Task extension code storing an unvalidated object in the annotation; a version mismatch where an older integration stored a different representation.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Functions/DurableTask/DurableTaskSchedulerResource.cs:45

    /// </summary>
    public bool IsEmulator => this.IsContainer();

    private ReferenceExpression CreateConnectionString()
    {
        if (IsEmulator)
        {
            var grpcEndpoint = new EndpointReference(this, "grpc");

            return ReferenceExpression.Create($"Endpoint={grpcEndpoint.Property(EndpointProperty.Scheme)}://{grpcEndpoint.Property(EndpointProperty.Host)}:{grpcEndpoint.Property(EndpointProperty.Port)};Authentication=None");
        }

        if (this.TryGetLastAnnotation<DurableTaskSchedulerConnectionStringAnnotation>(out var connectionStringAnnotation))
        {
            return connectionStringAnnotation.ConnectionString switch
            {
                ParameterResource parameterResource => ReferenceExpression.Create($"{parameterResource}"),
                string value => ReferenceExpression.Create($"{value}"),
                _ => throw new InvalidOperationException($"Unexpected connection string type: {connectionStringAnnotation.ConnectionString.GetType().Name}"),
            };
        }

        throw new InvalidOperationException($"Unable to resolve the Durable Task Scheduler connection string. Configure the scheduler using {nameof(DurableTaskResourceExtensions.RunAsEmulator)}() or {nameof(DurableTaskResourceExtensions.RunAsExisting)}(connectionString) before accessing {nameof(ConnectionStringExpression)}.");
    }

    private ReferenceExpression CreateDashboardEndpoint()
    {
        if (IsEmulator)
        {
            var dashboardEndpoint = new EndpointReference(this, "dashboard");

            return ReferenceExpression.Create($"{dashboardEndpoint.Property(EndpointProperty.Url)}");
        }

        throw new InvalidOperationException("Dashboard endpoint is only available when running as an emulator.");
    }
}

View on GitHub (pinned to 25830f84bd)