{"record":{"id":"ed0eaa3ac204bd2f","repo":"microsoft/aspire","slug":"unable-to-read-the-output-of-cargo-metadata-for-the-rust-app","errorCode":null,"errorMessage":"Unable to read the output of 'cargo metadata' for the Rust app '{resourceName}'. Cargo returned invalid {ex.GetType().Name} output.","messagePattern":"Unable to read the output of 'cargo metadata' for the Rust app '(.+?)'\\. Cargo returned invalid (.+?) output\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Rust/CargoMetadataReader.cs","lineNumber":137,"sourceCode":"\n        var stdout = await stdoutTask.ConfigureAwait(false);\n        var stderr = await stderrTask.ConfigureAwait(false);\n\n        if (process.ExitCode != 0)\n        {\n            var diagnostic = FormatStandardError(stderr, environment, startInfo.Environment);\n            var diagnosticSuffix = diagnostic.Length > 0 ? $\" {diagnostic}\" : string.Empty;\n            throw new DistributedApplicationException(\n                $\"'cargo metadata' failed for the Rust app '{resourceName}' with exit code {process.ExitCode}.{diagnosticSuffix}\");\n        }\n\n        try\n        {\n            return CargoMetadata.Parse(stdout);\n        }\n        catch (Exception ex) when (ex is not DistributedApplicationException)\n        {\n            throw new DistributedApplicationException(\n                $\"Unable to read the output of 'cargo metadata' for the Rust app '{resourceName}'. Cargo returned invalid {ex.GetType().Name} output.\");\n        }\n    }\n\n    internal static string FormatStandardError(\n        string standardError,\n        IReadOnlyDictionary<string, string> environment,\n        IEnumerable<KeyValuePair<string, string?>>? inheritedEnvironment = null)\n    {\n        // Cargo wrappers and configuration errors can echo values from the resolved resource environment or\n        // inherited variables such as CARGO_REGISTRY_TOKEN. Resource values are all user-controlled, while\n        // inherited values are limited to conventional secret-bearing names to preserve useful diagnostics.\n        // Redact before truncating so a value that crosses the retained-output boundary cannot leak partially.\n        if (string.IsNullOrWhiteSpace(standardError))\n        {\n            return string.Empty;\n        }\n","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Rust/CargoMetadataReader.cs#L119-L155","documentation":"Once 'cargo metadata' exits successfully, ReadAsync passes stdout to CargoMetadata.Parse. If parsing throws any exception other than DistributedApplicationException (e.g. JsonException from malformed JSON), it is wrapped in DistributedApplicationException stating that cargo returned invalid output, preserving the original exception type name.","triggerScenarios":"cargo exits 0 but its stdout is not valid/expected 'cargo metadata --format-version 1' JSON — e.g. extra banner text, output written by a wrapper script, truncation, or a shim that prints diagnostics to stdout.","commonSituations":"A 'cargo' shim/alias on PATH that injects extra output; tooling that mutates cargo behavior (cargo-wrap scripts); output truncated by an intermediary; cargo printing warnings into the redirected stream in an unexpected format.","solutions":["Run 'cargo metadata --format-version 1' manually in the resource directory and inspect stdout for non-JSON content.","Remove any cargo shim/wrapper/alias so the real cargo binary is invoked, or make the wrapper pass stdout through untouched.","Check for hooks or environment (RUSTFLAGS, custom config, plugin scripts) that cause cargo to emit extra stdout.","Update the Rust toolchain if the installed cargo emits an unexpected metadata schema, then retry."],"exampleFix":"// diagnose non-JSON cargo output\n// before\n$ which cargo\n /usr/local/bin/cargo  # a wrapper script printing banners\n\n// after\n$ which cargo\n ~/.cargo/bin/cargo     # real cargo; stdout is pure JSON","handlingStrategy":"validation","validationCode":"# Ensure cargo emits clean JSON:\ncargo metadata --format-version 1 | python -c 'import json,sys; json.load(sys.stdin)' && echo OK","typeGuard":null,"tryCatchPattern":"try { /* start Rust resource */ }\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"Cargo returned invalid\"))\n{ /* inspect raw cargo stdout for non-JSON content */ }","preventionTips":["Remove cargo shims/aliases/wrappers that inject output into stdout.","Verify 'cargo metadata --format-version 1' stdout parses as pure JSON in your environment.","Avoid tools or hooks that post-process or truncate cargo output on PATH."],"tags":["rust","cargo","json","parse"],"backgroundTag":"invalid-json-response","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"}