microsoft/aspire · error · EmptyChoicesException

No items available for selection

Error message

No items available for selection: {0}

What it means

PromptForSelectionAsync validates the choices collection before showing the picker and throws EmptyChoicesException when it is empty, avoiding a less clear InvalidOperationException from the prompt library deeper down. The {0} placeholder is filled with the prompt text.

Solutions

  1. Check the collection for elements before prompting and exit with a helpful message when empty.
  2. Fix the data source so it actually returns choices (e.g. install templates, fix feed connectivity).
  3. Guard the call with a non-empty assertion in tests.
  4. Provide a default fallback choice when the source can legitimately be empty.

Example fix

// before
await interaction.PromptForSelectionAsync("Pick a template", templates, t => t.Name);
// after
if (templates.Count == 0)
{
    interaction.DisplayError("No templates available. Run 'dotnet new install' first.");
    return 1;
}
await interaction.PromptForSelectionAsync("Pick a template", templates, t => t.Name);
Defensive patterns

Strategy: validation

Validate before calling

if (choices is null || choices.Count == 0)
{
    interaction.DisplayError("No options available to select.");
    return ExitCodeConstants.FailedToCreateNewProject;
}

Type guard

bool hasChoices = choices is { Count: > 0 };

Try / catch

try { await interaction.PromptForSelectionAsync(prompt, choices, fmt); }
catch (EmptyChoicesException ex)
{
    interaction.DisplayError(ex.Message);
    return ExitCodeConstants.FailedToCreateNewProject;
}

Prevention

When it happens

Trigger: Calling PromptForSelectionAsync with an empty choices list (or a collection whose deferred evaluation yields no items) regardless of interactivity.

Common situations: Enumerating available templates/channels/environments that returned zero results (e.g. network feed empty, no installed templates) and passing the empty result straight to the prompt; an upstream filter removing all candidates.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Interaction/ConsoleInteractionService.cs:319

        if (!_hostEnvironment.SupportsInteractiveInput)
        {
            if (binding != null)
            {
                if (binding.NonInteractiveDefaultValue != null)
                {
                    return MatchChoiceOrThrow(binding.NonInteractiveDefaultValue, binding, choicesList, choiceFormatter);
                }

                ThrowNonInteractiveError(binding.SymbolDisplayName);
            }

            throw new InvalidOperationException(InteractionServiceStrings.InteractiveInputNotSupported);
        }

        // Check if the choices collection is empty to avoid throwing an InvalidOperationException
        if (choicesList.Count == 0)
        {
            throw new EmptyChoicesException(string.Format(CultureInfo.CurrentCulture, InteractionServiceStrings.NoItemsAvailableForSelection, promptText));
        }

        // Buffer console logs while interactive prompts are active so
        // background debug output doesn't drown the prompt UI.
        using var promptScope = _logBufferContext.BeginInteractivePromptScope();

        MessageLogger.LogInformation("Selection prompt: {PromptText}", promptText);

        var prompt = new SelectionPrompt<T>()
            .Title(promptText)
            .UseConverter(choiceFormatter)
            .AddChoices(choicesList)
            .PageSize(10)
            .EnableSearch();

        prompt.SearchHighlightStyle = s_searchHighlightStyle;

        var result = await MessageConsole.PromptAsync(prompt, cancellationToken);

View on GitHub (pinned to 25830f84bd)