{"record":{"id":"8c2d42b9d3125a8d","repo":"microsoft/aspire","slug":"failed-to-parse-template-version-from-stdout","errorCode":null,"errorMessage":"Failed to parse template version from stdout.","messagePattern":"Failed to parse template version from stdout\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/DotNet/DotNetCliRunner.cs","lineNumber":1145,"sourceCode":"            if (stdout is null)\n            {\n                logger.LogError(\"Failed to read stdout from the process. This should never happen.\");\n                return (CliExitCodes.FailedToInstallTemplates, null);\n            }\n\n            // NOTE: This parsing logic is hopefully temporary and in the future we'll\n            //       have structured output:\n            //\n            //       See: https://github.com/dotnet/sdk/issues/46345\n            //\n            if (!TryParsePackageVersionFromStdout(stdout, out var parsedVersion))\n            {\n                logger.LogError(\"Failed to parse template version from stdout.\");\n\n                // Throwing here because this should never happen - we don't want to return\n                // the zero exit code if we can't parse the version because its possibly a\n                // signal that the .NET SDK has changed.\n                throw new InvalidOperationException(ErrorStrings.FailedToParseTemplateVersionFromStdout);\n            }\n\n            return (exitCode, parsedVersion);\n        }\n    }\n\n    private async Task UninstallTemplateAsync(string packageName, DirectoryInfo workingDirectory, CancellationToken cancellationToken)\n    {\n        var exitCode = await ExecuteAsync(\n            args: [\"new\", \"uninstall\", packageName],\n            env: new Dictionary<string, string>\n            {\n                [KnownConfigNames.DotnetCliUiLanguage] = \"en-US\"\n            },\n            projectFile: null,\n            workingDirectory: workingDirectory,\n            backchannelCompletionSource: null,\n            options: new ProcessInvocationOptions","sourceCodeStart":1127,"sourceCodeEnd":1163,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/DotNet/DotNetCliRunner.cs#L1127-L1163","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (assuming old format)\n// parser expected: \"Template Name (aspire) vX.Y.Z\"\n// after: update regex to match new SDK output shape, e.g.\nvar match = Regex.Match(stdout, @\"version\\s+(?<version>[0-9.]+)\");","handlingStrategy":"try-catch","validationCode":"// Run the SDK command and check output format before relying on the parsed version\nvar psi = new ProcessStartInfo(\"dotnet\", \"new --list\");\nvar stdout = await Process.Start(psi)!.StandardOutput.ReadToEndAsync();\nif (!stdout.Contains(\"aspire\"))\n    throw new InvalidOperationException(\"Aspire templates not present or SDK output format changed.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var (exitCode, version) = await runner.GetNewTemplatesDefaultVersionAsync(...);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"template version\"))\n{\n    logger.LogError(ex, \"Could not parse template version; check .NET SDK version and output format.\");\n}","preventionTips":["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."],"tags":["cli","dotnet-sdk","parsing"],"backgroundTag":"unexpected-response-shape","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}