{"record":{"id":"9045cd5f5c2f1d78","repo":"microsoft/aspire","slug":"cancellationmessage","errorCode":null,"errorMessage":"{cancellationMessage}","messagePattern":"\\{cancellationMessage\\}","errorType":"exception","errorClass":"OperationCanceledException","httpStatus":null,"severity":"warning","filePath":"src/Aspire.Hosting/ApplicationModel/ResourceNotificationService.cs","lineNumber":693,"sourceCode":"                {\n                    continue;\n                }\n\n                activity.AddResourceWaitObserved(resourceEvent, waitCondition);\n\n                if (predicate(resourceEvent))\n                {\n                    activity.AddResourceWaitCompleted(resourceEvent, waitCondition);\n                    return resourceEvent;\n                }\n            }\n        }\n        catch (OperationCanceledException ex)\n        {\n            activity.AddResourceWaitCancelled(resourceName, waitCondition);\n\n            var errorMessage = BuildCancellationErrorMessage(cancellationMessage, resourceName);\n            throw new OperationCanceledException(errorMessage, ex, ex.CancellationToken);\n        }\n\n        throw new OperationCanceledException(BuildCancellationErrorMessage(cancellationMessage, resourceName));\n    }\n    private readonly object _onResourceUpdatedLock = new();\n\n    /// <summary>\n    /// Attempts to retrieve the current state of a resource by resourceId.\n    /// </summary>\n    /// <remarks>\n    /// <para>\n    /// A resource id can be either the unique id of the resource or the displayed resource name.\n    /// </para>\n    /// <para>\n    /// Projects, executables and containers typically have a unique id that combines the display name and a unique suffix. For example, a resource named <c>cache</c> could have a resource id of <c>cache-abcdwxyz</c>.\n    /// This id is used to uniquely identify the resource in the app host.\n    /// </para>\n    /// <para>","sourceCodeStart":675,"sourceCodeEnd":711,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/ApplicationModel/ResourceNotificationService.cs#L675-L711","documentation":"Thrown by WaitForResourceCoreAsync when waiting for a resource condition (running/healthy/etc.) is cancelled. If cancellation came from an OperationCanceledException it is rethrown with an enriched message; otherwise it throws OperationCanceledException directly, indicating the wait ended without the condition ever being met.","triggerScenarios":"WaitForResource/WaitForResourceHealthy/WaitUntil* calls whose CancellationToken fires (Ctrl+C, AppHost shutdown, host-level timeout) while the resource never reached the requested waitCondition; also the fall-through path when the wait completes without a satisfying event.","commonSituations":"Resource takes longer to start than the surrounding timeout allows (slow image pull, slow health check registration); user aborts `aspire run`; CI test harness cancels AppHost startup.","solutions":["Increase the timeout / cancellation budget around AppHost startup where applicable.","Speed up resource startup (pre-pull images, simplify health checks) so waits complete before cancellation.","Confirm the waitCondition target is actually attainable (e.g. resource exposes health endpoints for 'healthy').","Catch OperationCanceledException in host code to distinguish user-initiated cancellation from genuine startup stalls."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    await notificationService.WaitForResourceHealthyAsync(resourceName, cancellationToken);\n}\ncatch (OperationCanceledException ex)\n{\n    logger.LogWarning(ex, \"Wait for '{ResourceName}' was cancelled before it became healthy.\", resourceName);\n}","preventionTips":["Grant startup enough time: avoid overly tight cancellation timeouts in CI/tests.","Ensure the awaited condition is achievable (health endpoints exist for 'healthy').","Speed up startup (image pre-pull, lighter health checks) to beat cancellation.","Distinguish user-initiated cancels from stalls by logging the inner cancellation source."],"tags":["aspire","cancellation","resource-wait","timeout"],"backgroundTag":"request-timeout","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}