{"record":{"id":"e33634c877cbdedb","repo":"microsoft/aspire","slug":"resource-resource-name-stopped-waiting-for-dependency-e33634","errorCode":null,"errorMessage":"Resource '{resource.Name}' stopped waiting for dependency resource '{displayName}' because it entered the '{snapshot.State.Text}' state prematurely.","messagePattern":"Resource '(.+?)' stopped waiting for dependency resource '(.+?)' because it entered the '(.+?)' state prematurely\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/ApplicationModel/ResourceNotificationService.cs","lineNumber":420,"sourceCode":"                {\n                    resourceLogger.LogError(\n                        \"Dependency resource '{ResourceName}' failed to start.\",\n                        displayName\n                        );\n\n                    throw new DistributedApplicationException($\"Resource '{resource.Name}' stopped waiting for dependency resource '{displayName}' because it failed to start.\");\n                }\n                else if (snapshot.State!.Text == KnownResourceStates.Finished ||\n                         snapshot.State.Text == KnownResourceStates.Exited ||\n                         snapshot.State.Text == KnownResourceStates.RuntimeUnhealthy)\n                {\n                    resourceLogger.LogError(\n                        \"Resource '{ResourceName}' has entered the '{State}' state prematurely.\",\n                        displayName,\n                        snapshot.State.Text\n                        );\n\n                    throw new DistributedApplicationException(\n                        $\"Resource '{resource.Name}' stopped waiting for dependency resource '{displayName}' because it entered the '{snapshot.State.Text}' state prematurely.\"\n                        );\n                }\n            }\n\n            // Execute the post-running action specific to the wait type\n            await postRunningAction(resourceLogger, displayName, resourceId, resourceEvent).ConfigureAwait(false);\n\n            if (onDependencyReady is not null)\n            {\n                await onDependencyReady(resourceId).ConfigureAwait(false);\n            }\n\n            static bool IsContinuableState(WaitBehavior waitBehavior, CustomResourceSnapshot snapshot) =>\n                waitBehavior switch\n                {\n                    WaitBehavior.WaitOnResourceUnavailable => snapshot.State?.Text == KnownResourceStates.Running,\n                    WaitBehavior.StopOnResourceUnavailable => snapshot.State?.Text == KnownResourceStates.Running ||","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/ResourceNotificationService.cs#L402-L438","documentation":"Thrown by WaitUntilStateAsync when, under StopOnResourceUnavailable behavior, the dependency resource enters a terminal/unavailable state (Finished, Exited, RuntimeUnhealthy) before reaching the awaited state. Aspire aborts the wait with a message identifying the premature state.","triggerScenarios":"WaitFor/WaitUntilHealthy/WaitUntilStarted with WaitBehavior.StopOnResourceUnavailable while the dependency transitions to Finished, Exited, or RuntimeUnhealthy before becoming Running/Healthy.","commonSituations":"Dependency process exits early after a crash; runtime health checks (e.g. container liveness) mark the resource RuntimeUnhealthy; dependency is a short-lived job being awaited with a healthy-state wait instead of WaitForCompletion.","solutions":["Check dependency logs for the reason it exited or became runtime-unhealthy.","If the dependency is a batch job, replace WaitFor/WaitUntilHealthy with WaitForCompletion and an expected exit code.","Fix health configuration (health checks, probes, resource limits) that causes RuntimeUnhealthy.","Use WaitBehavior.WaitOnResourceUnavailable if the dependency legitimately cycles and you want to keep waiting."],"exampleFix":"// before\nbuilder.AddProject<Projects.Worker>(\"worker\")\n    .WaitFor(\"seeder\"); // seeder is a one-shot job that exits\n\n// after\nbuilder.AddProject<Projects.Worker>(\"worker\")\n    .WaitForCompletion(\"seeder\", exitCode: 0);","handlingStrategy":"validation","validationCode":"// Only wait for Running/Healthy on resources designed to stay up; for one-shot jobs use:\n// builder.WaitForCompletion(name, exitCode: 0);","typeGuard":null,"tryCatchPattern":"try\n{\n    await app.StartAsync();\n}\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"prematurely\"))\n{\n    logger.LogError(ex, \"Dependency exited before reaching the awaited state.\");\n}","preventionTips":["Match wait type to resource lifecycle: WaitForCompletion for jobs, WaitFor for servers.","Fix crashes/probe configs causing Finished/Exited/RuntimeUnhealthy before Running.","Review dependency logs to catch early exits during local development.","Consider WaitBehavior.WaitOnResourceUnavailable for resources that restart transiently."],"tags":["aspire","dependency","premature-exit","orchestration"],"backgroundTag":"invalid-state-transition","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"}