{"record":{"id":"29b887bd6a76ce23","repo":"microsoft/aspire","slug":"nameof-interactionservice-is-not-available-because-the","errorCode":null,"errorMessage":"{nameof(InteractionService)} is not available because the dashboard is not enabled or because this command is running in non-interactive CLI mode.","messagePattern":"(.+?) is not available because the dashboard is not enabled or because this command is running in non-interactive CLI mode\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/InteractionService.cs","lineNumber":689,"sourceCode":"                yield return item;\n            }\n        }\n        finally\n        {\n            lock (_onInteractionUpdatedLock)\n            {\n                OnInteractionUpdated -= WriteToChannel;\n            }\n\n            channel.Writer.TryComplete();\n        }\n    }\n\n    private void EnsureServiceAvailable()\n    {\n        if (!IsAvailable)\n        {\n            throw new InvalidOperationException($\"{nameof(InteractionService)} is not available because the dashboard is not enabled or because this command is running in non-interactive CLI mode.\");\n        }\n    }\n}\n\ninternal class InteractionCollection : KeyedCollection<int, Interaction>\n{\n    protected override int GetKeyForItem(Interaction item) => item.InteractionId;\n}\n\n[DebuggerDisplay(\"State = {State}, Complete = {Complete}\")]\ninternal sealed class InteractionCompletionState\n{\n    public bool Complete { get; init; }\n    public object? State { get; init; }\n}\n\n[DebuggerDisplay(\"InteractionId = {InteractionId}, State = {State}, Title = {Title}\")]\ninternal class Interaction","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/InteractionService.cs#L671-L707","documentation":"InteractionService throws InvalidOperationException when any of its prompt methods (message box, inputs, notification, progress) is called while the service is not available. IsAvailable is false when the AppHost runs without the dashboard enabled, or when the command runs in non-interactive CLI mode where no UI exists to render prompts. The library throws eagerly instead of silently blocking or returning a default because a caller expecting user interaction cannot proceed meaningfully.","triggerScenarios":"Calling InteractionService.PromptMessageBoxAsync, PromptInputsAsync, PromptNotificationAsync, or PromptProgressAsync (directly or via an eventing subscriber/resource notification) when IsAvailable is false — i.e. dashboard is disabled (ASPIRE_DASHBOARD_DISABLED or no dashboard resource) or the process runs under non-interactive CLI commands such as `aspire run` in pipelines, `aspire publish`, or CI.","commonSituations":"Running an AppHost in CI/CD where no dashboard is attached; invoking prompts from custom event handlers or resource lifecycle code that works locally but fails in `aspire publish` or non-interactive terminals; disabling the dashboard for performance and forgetting code depends on interactions.","solutions":["Check InteractionService.IsAvailable before prompting and skip or fall back to defaults when false.","Enable the dashboard (remove dashboard disable flags / run via `aspire run` interactively) if the interaction is required.","Wrap prompt calls in try-catch on InvalidOperationException and degrade gracefully (log, use default value) for non-interactive environments.","Gate interaction-dependent code behind an environment/configuration check so it never runs in headless/CI contexts."],"exampleFix":"// before\nvar answer = await interactionService.PromptMessageBoxAsync(new MessageBoxInteractionOptions { ... });\n\n// after\nif (interactionService.IsAvailable)\n{\n    var answer = await interactionService.PromptMessageBoxAsync(new MessageBoxInteractionOptions { ... });\n}\nelse\n{\n    logger.LogInformation(\"Skipping prompt: dashboard not enabled or non-interactive mode.\");\n}","handlingStrategy":"validation","validationCode":"if (!interactionService.IsAvailable)\n{\n    logger.LogWarning(\"InteractionService unavailable; using default instead of prompting.\");\n    return defaultValue;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    result = await interactionService.PromptMessageBoxAsync(options);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"InteractionService\"))\n{\n    logger.LogWarning(ex, \"Prompt unavailable; falling back to default.\");\n    result = defaultValue;\n}","preventionTips":["Always check InteractionService.IsAvailable before any prompt call.","Never assume interactive mode: CI, publish, and non-interactive CLI runs have no dashboard.","Provide non-interactive defaults for every prompt so headless runs can proceed.","Test AppHosts with the dashboard disabled to surface interaction dependencies."],"tags":["aspire","dashboard","interactivity","headless"],"backgroundTag":"feature-not-enabled","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"}