microsoft/aspire · error · InvalidOperationException
Failed to parse template version from stdout.
Error message
Failed to parse template version from stdout.
What it means
DotNetCliRunner's template-version parsing expects 'dotnet new' output to contain a parseable template version; when stdout does not match, it logs the failure and throws InvalidOperationException because returning a zero exit code with no version would mask a possible .NET SDK behavior change.
Solutions
- Check which .NET SDK version is installed (dotnet --version) and test the underlying 'dotnet new' command manually to inspect its output format.
- Verify the Aspire templates are installed (dotnet new install Aspire.Templates) and the SDK is a supported version.
- If the SDK output format changed, update the parsing logic in DotNetCliRunner to match the new format.
- Ensure the process is not running under a locale/culture that localizes SDK output, or set DOTNET_CLI_UI_LANGUAGE=en.
Example fix
// before (assuming old format) // parser expected: "Template Name (aspire) vX.Y.Z" // after: update regex to match new SDK output shape, e.g. var match = Regex.Match(stdout, @"version\s+(?<version>[0-9.]+)");
Defensive patterns
Strategy: try-catch
Validate before calling
// Run the SDK command and check output format before relying on the parsed version
var psi = new ProcessStartInfo("dotnet", "new --list");
var stdout = await Process.Start(psi)!.StandardOutput.ReadToEndAsync();
if (!stdout.Contains("aspire"))
throw new InvalidOperationException("Aspire templates not present or SDK output format changed."); Try / catch
try
{
var (exitCode, version) = await runner.GetNewTemplatesDefaultVersionAsync(...);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("template version"))
{
logger.LogError(ex, "Could not parse template version; check .NET SDK version and output format.");
} Prevention
- Pin to supported .NET SDK versions; retest template parsing after SDK upgrades.
- Verify Aspire template packs are installed (dotnet new list aspire).
- Set DOTNET_CLI_UI_LANGUAGE=en to avoid localized output breaking parsers.
When it happens
Trigger: Running the new/template listing command where the SDK stdout layout changed (SDK upgrade), localized SDK output, empty stdout due to the command failing silently, or output redirection losing lines.
Common situations: After installing a new .NET SDK version whose 'dotnet new' output format differs; non-English locale emitting translated SDK messages; ASP.NET/Aspire template packs missing or partially installed.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Could not parse Helm version from 'helm version --short'…
- Integration closure metadata line
- Invalid value " " for "--dcp-dependency-check-timeout"…
- {parse errors joined by '; '}
- Already connected to AppHost backchannel.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/8c2d42b9d3125a8d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Cli/DotNet/DotNetCliRunner.cs:1145
if (stdout is null)
{
logger.LogError("Failed to read stdout from the process. This should never happen.");
return (CliExitCodes.FailedToInstallTemplates, null);
}
// NOTE: This parsing logic is hopefully temporary and in the future we'll
// have structured output:
//
// See: https://github.com/dotnet/sdk/issues/46345
//
if (!TryParsePackageVersionFromStdout(stdout, out var parsedVersion))
{
logger.LogError("Failed to parse template version from stdout.");
// Throwing here because this should never happen - we don't want to return
// the zero exit code if we can't parse the version because its possibly a
// signal that the .NET SDK has changed.
throw new InvalidOperationException(ErrorStrings.FailedToParseTemplateVersionFromStdout);
}
return (exitCode, parsedVersion);
}
}
private async Task UninstallTemplateAsync(string packageName, DirectoryInfo workingDirectory, CancellationToken cancellationToken)
{
var exitCode = await ExecuteAsync(
args: ["new", "uninstall", packageName],
env: new Dictionary<string, string>
{
[KnownConfigNames.DotnetCliUiLanguage] = "en-US"
},
projectFile: null,
workingDirectory: workingDirectory,
backchannelCompletionSource: null,
options: new ProcessInvocationOptionsView on GitHub (pinned to 25830f84bd)