{"record":{"id":"0bd49ca379fe9e5d","repo":"microsoft/aspire","slug":"failed-to-parse-json-output-into-type-typename-output","errorCode":null,"errorMessage":"Failed to parse JSON output into type '{typeName}':\n{output}","messagePattern":"Failed to parse JSON output into type '(.+?)':\n(.+?)","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.DevTunnels/DevTunnelCliClient.cs","lineNumber":339,"sourceCode":"            logger?.LogError(\"CLI call returned empty output with exit code '{ExitCode}'.\", exitCode);\n            return (default, exitCode, \"CLI call returned empty output.\");\n        }\n\n        try\n        {\n            if (!string.IsNullOrEmpty(propertyName))\n            {\n                output = JsonDocument.Parse(output).RootElement.GetProperty(propertyName).GetRawText();\n                logger?.LogTrace(\"Extracted JSON property '{PropertyName}':\\n{Output}\", propertyName, output);\n            }\n            var result = JsonSerializer.Deserialize<T>(output, _jsonOptions);\n            logger?.LogTrace(\"JSON output successfully deserialized to '{TypeName}' instance\", typeof(T).Name);\n            return (result, 0, default);\n        }\n        catch (JsonException ex)\n        {\n            logger?.LogError(ex, \"Failed to parse JSON output into type '{TypeName}':\\n{Output}\", typeof(T).Name, output);\n            throw new DistributedApplicationException($\"Failed to parse JSON output into type '{typeof(T).Name}':\\n{output}\", ex);\n        }\n    }\n\n    private record DevTunnelDeleteResult(string DeletedTunnel);\n}\n","sourceCodeStart":321,"sourceCodeEnd":345,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.DevTunnels/DevTunnelCliClient.cs#L321-L345","documentation":"CallCliAsJsonAsync captures the devtunnel CLI's stdout and deserializes it into type T. If the output is not valid JSON (JsonException), the client logs the raw output and rethrows it wrapped in this DistributedApplicationException.","triggerScenarios":"The devtunnel CLI prints human-readable text, warnings, or login prompts to stdout instead of JSON; an old CLI version emits a different output shape; the command fails before producing JSON.","commonSituations":"Outdated devtunnel CLI without JSON output support for a flag; CLI emitting deprecation/telemetry banners on stdout; truncation or interleaved stderr/stdout in redirected streams.","solutions":["Update the devtunnel CLI to the latest version so JSON output matches what Aspire expects","Read the raw output in the message to see exactly what the CLI returned","Verify the command succeeds when run manually (`devtunnel list --json`) and compare output","Check whether another tool/alias named `devtunnel` is shadowing the real CLI on PATH"],"exampleFix":"// before\n// devtunnel CLI v0.1 prints text banners -> JsonException\n// after\n// update CLI\ndevtunnel update  # or reinstall latest from https://learn.microsoft.com/azure/developer/dev-tunnels\n// then retry the app host","handlingStrategy":"validation","validationCode":"var psi = new ProcessStartInfo(\"devtunnel\", \"--version\") { RedirectStandardOutput = true };\nusing var p = Process.Start(psi)!;\nvar version = (await p.StandardOutput.ReadToEndAsync()).Trim();\nif (Version.TryParse(version.Split(' ')[^1].TrimStart('v'), out var v) && v < new Version(1, 0))\n    throw new InvalidOperationException($\"devtunnel CLI too old: {version}\");","typeGuard":"static bool LooksLikeJson(string s) => s.TrimStart().StartsWith('{') || s.TrimStart().StartsWith('[');","tryCatchPattern":"try { await client.ListTunnelsAsync(logger, ct); }\ncatch (DistributedApplicationException ex) when (ex.Message.StartsWith(\"Failed to parse JSON\"))\n{ logger.LogError(ex, \"devtunnel CLI returned non-JSON output; update the CLI\"); throw; }","preventionTips":["Keep the devtunnel CLI up to date","Run the failing command manually with --json to inspect raw output","Ensure no alias shadows devtunnel on PATH"],"tags":["devtunnels","cli","json"],"backgroundTag":"json-parse-error","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}