microsoft/aspire · error · InvalidOperationException

is not available because the dashboard is not enabled or…

Error message

{nameof(InteractionService)} is not available because the dashboard is not enabled or because this command is running in non-interactive CLI mode.

What it means

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.

Solutions

  1. Check InteractionService.IsAvailable before prompting and skip or fall back to defaults when false.
  2. Enable the dashboard (remove dashboard disable flags / run via `aspire run` interactively) if the interaction is required.
  3. Wrap prompt calls in try-catch on InvalidOperationException and degrade gracefully (log, use default value) for non-interactive environments.
  4. Gate interaction-dependent code behind an environment/configuration check so it never runs in headless/CI contexts.

Example fix

// before
var answer = await interactionService.PromptMessageBoxAsync(new MessageBoxInteractionOptions { ... });

// after
if (interactionService.IsAvailable)
{
    var answer = await interactionService.PromptMessageBoxAsync(new MessageBoxInteractionOptions { ... });
}
else
{
    logger.LogInformation("Skipping prompt: dashboard not enabled or non-interactive mode.");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!interactionService.IsAvailable)
{
    logger.LogWarning("InteractionService unavailable; using default instead of prompting.");
    return defaultValue;
}

Try / catch

try
{
    result = await interactionService.PromptMessageBoxAsync(options);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("InteractionService"))
{
    logger.LogWarning(ex, "Prompt unavailable; falling back to default.");
    result = defaultValue;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/InteractionService.cs:689

                yield return item;
            }
        }
        finally
        {
            lock (_onInteractionUpdatedLock)
            {
                OnInteractionUpdated -= WriteToChannel;
            }

            channel.Writer.TryComplete();
        }
    }

    private void EnsureServiceAvailable()
    {
        if (!IsAvailable)
        {
            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.");
        }
    }
}

internal class InteractionCollection : KeyedCollection<int, Interaction>
{
    protected override int GetKeyForItem(Interaction item) => item.InteractionId;
}

[DebuggerDisplay("State = {State}, Complete = {Complete}")]
internal sealed class InteractionCompletionState
{
    public bool Complete { get; init; }
    public object? State { get; init; }
}

[DebuggerDisplay("InteractionId = {InteractionId}, State = {State}, Title = {Title}")]
internal class Interaction

View on GitHub (pinned to 25830f84bd)