fullstackhero/dotnet-starter-kit · error · InvalidOperationException

Project name is required in non-interactive mode. Pass it…

Error message

Project name is required in non-interactive mode. Pass it as: fsh new <name>

What it means

The `fsh new` CLI command requires a project name. When running with --non-interactive (CI/scripted usage) and no name was supplied via `fsh new <name>` or settings, ResolveNameAsync throws InvalidOperationException because it cannot fall back to an interactive TextPrompt.

Solutions

  1. Pass the project name positionally: `fsh new MyProject --non-interactive`.
  2. Set the project name in the CLI settings/input the command reads (settings.Name) so ResolveNameAsync short-circuits before the check.
  3. Remove --non-interactive when running in an interactive terminal so the TextPrompt can ask for the name.
  4. In CI, supply the name via an env/variable interpolated into the command line, e.g. `fsh new $PROJECT_NAME --non-interactive`.

Example fix

// before (CI step)
- run: fsh new --non-interactive
// after
- run: fsh new ${{ inputs.projectName }} --non-interactive
Defensive patterns

Strategy: validation

Validate before calling

// shell pre-check
if [ -z "$PROJECT_NAME" ]; then echo 'PROJECT_NAME is required with --non-interactive'; exit 1; fi
fsh new "$PROJECT_NAME" --non-interactive

Try / catch

try {
  await run('fsh', ['new', '--non-interactive']);
} catch (e) {
  if (String(e).includes('Project name is required')) {
    throw new Error('Add a positional name: fsh new <name> --non-interactive');
  } throw e;
}

Prevention

When it happens

Trigger: Running `fsh new --non-interactive` (or a non-TTY environment where interactivity is disabled) without a positional name argument; a settings file/pipeline that omits Name while non-interactive mode is on; invoking the command from a script or CI job with missing arguments.

Common situations: CI pipelines (GitHub Actions, Docker builds) without a TTY that force non-interactive mode; scripts copied from a colleague that dropped the name argument; documentation examples omitting that non-interactive mode requires the positional name.

Understand the failure class

Background: "no subcommand specified" and "... is required": CLI errors when a required argument is missing — this error's family across 13 libraries.

Related errors


AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15). Data as JSON: /api/errors/f7e7c33840d7f228. Report an issue: GitHub.

Appendix: source

Thrown at src/Tools/CLI/Commands/NewCommand.cs:149

        // 10. Print next steps
        PrintNextSteps(name, aspire, frontend, settings.SkipInstall, dockerEnvReady);

        return 0;
    }

    private static void PrintBanner()
    {
        AnsiConsole.Write(new FigletText("fsh").Color(Color.DodgerBlue1));
        AnsiConsole.MarkupLine("[bold]FullStackHero .NET Starter Kit[/]");
        AnsiConsole.WriteLine();
    }

    private static async Task<string> ResolveNameAsync(Settings settings, CancellationToken cancellationToken)
    {
        if (settings.Name is not null) return settings.Name;

        if (settings.NonInteractive)
            throw new InvalidOperationException("Project name is required in non-interactive mode. Pass it as: fsh new <name>");

        return await new TextPrompt<string>($"[{FshConstants.AccentColor}]Project name:[/]")
            .Validate(input =>
            {
                string? error = ProjectNameValidator.Validate(input);
                return error is null
                    ? ValidationResult.Success()
                    : ValidationResult.Error(error);
            })
            .ShowAsync(AnsiConsole.Console, cancellationToken).ConfigureAwait(false);
    }

    private static async Task<bool> ResolveAspireAsync(Settings settings, CancellationToken cancellationToken)
    {
        if (settings.NoAspire) return false;
        if (settings.NonInteractive) return true;

        return await new ConfirmationPrompt($"[{FshConstants.AccentColor}]Include .NET Aspire AppHost?[/]")

View on GitHub (pinned to 3f2959e683)