microsoft/aspire · error · InvalidOperationException

Unable to resolve the Durable Task Scheduler connection…

Error message

Unable to resolve the Durable Task Scheduler connection string. Configure the scheduler using RunAsEmulator() or RunAsExisting(connectionString) before accessing ConnectionStringExpression.

What it means

When no DurableTaskSchedulerConnectionStringAnnotation exists at all, CreateConnectionString throws this InvalidOperationException explaining that the scheduler must first be configured with RunAsEmulator() or RunAsExisting(connectionString) before its ConnectionStringExpression can be read. It prevents dependent resources (e.g., task hubs, Functions apps) from resolving an undefined connection string.

Solutions

  1. Call .RunAsEmulator() (local development) or .RunAsExisting(connectionStringOrParameter) on the DurableTaskSchedulerResource builder before referencing its connection string.
  2. Ensure dependent resources are added after the scheduler is configured in run mode.
  3. For deploy-only scenarios, provide the connection string via RunAsExisting with a parameter so it exists in the model.

Example fix

// before
var scheduler = builder.AddDurableTaskScheduler("scheduler");
var functions = builder.AddAzureFunctionsProject<Projects.FuncApp>("funcapp")
    .WithReference(scheduler); // no connection configured

// after
var scheduler = builder.AddDurableTaskScheduler("scheduler")
    .RunAsExisting(builder.AddParameter("scheduler-conn"));
var functions = builder.AddAzureFunctionsProject<Projects.FuncApp>("funcapp")
    .WithReference(scheduler);
Defensive patterns

Strategy: validation

Validate before calling

bool configured = schedulerResource.Annotations.OfType<DurableTaskSchedulerConnectionStringAnnotation>().Any();
if (!configured) throw new InvalidOperationException("Call RunAsEmulator() or RunAsExisting(...) before reading the scheduler connection string.");

Type guard

static bool IsSchedulerConfigured(DurableTaskSchedulerResource r) => r.Annotations.OfType<DurableTaskSchedulerConnectionStringAnnotation>().Any();

Try / catch

try { var expr = scheduler.ConnectionStringExpression; } catch (InvalidOperationException ex) when (ex.Message.Contains("RunAsEmulator")) { /* configure run mode, then retry */ }

Prevention

When it happens

Trigger: Accessing schedulerResource.ConnectionStringExpression (or adding a consuming resource that reads it) without ever calling RunAsEmulator() or RunAsExisting() on the scheduler builder.

Common situations: Defining a Durable Task scheduler but forgetting run-mode configuration; wiring a Functions app to the scheduler in publish-only scenarios without RunAsExisting; ordering issues where the connection is read before configuration.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

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

    {
        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)