microsoft/aspire · error · DistributedApplicationException

Unable to work out which binary the Rust app

Error message

Unable to work out which binary the Rust app '{resourceName}' produces: the package '{package.Name}' declares {many.Count} binary targets. Call WithCargoBinTarget("<name>") to select one.

What it means

ResolveBinaryName throws this DistributedApplicationException when the resolved cargo package declares multiple (ambiguous) binary targets and the user has not selected one. Aspire cannot guess which executable to run or debug, so it fails fast listing the count and instructing the user to disambiguate with WithCargoBinTarget. This differs from the zero-binary-target error: here a valid choice exists, it just was not made.

Solutions

  1. Call .WithCargoBinTarget("<name>") on the resource to select one of the declared binaries
  2. Call .WithCargoPackage("<name>") to route through a specific package first, then select the binary
  3. Merge or remove unneeded [[bin]] targets in Cargo.toml if only one binary is intended

Example fix

// before
builder.AddRustApp("app", "../rust-multi-bin"); // declares 2 bin targets
// after
builder.AddRustApp("app", "../rust-multi-bin")
       .WithCargoBinTarget("my-server");
Defensive patterns

Strategy: validation

Validate before calling

var bins = ResolvePackageBinTargetNames(appDir);
if (bins.Count > 1) Console.WriteLine($"Ambiguous binaries: {string.Join(", ", bins)} — call WithCargoBinTarget.");

Type guard

bool HasSingleBinary(CargoPackage p) => p.BinTargetNames.Count == 1;

Try / catch

try { builder.AddRustApp("app", dir); } catch (DistributedApplicationException ex) when (ex.Message.Contains("WithCargoBinTarget")) { log.LogError(ex, "Ambiguous cargo bin target"); }

Prevention

When it happens

Trigger: Adding a RustAppResource whose package's BinTargetNames contains 2+ entries (e.g. multiple [[bin]] sections in Cargo.toml) without calling WithCargoBinTarget or WithCargoPackage to pick one.

Common situations: Crates that ship several binaries (cli + server, client + daemon) built from one Cargo.toml; adding a second [[bin]] target and then running the AppHost without updating the resource config.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/8925b33c460ca188. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Rust/RustCargoTargetResolver.cs:153

    private static string ResolveBinaryName(CargoMetadata metadata, string? requestedPackage, string resourceName)
    {
        var package = ResolvePackage(metadata, requestedPackage, resourceName);

        if (package.DefaultRun is { Length: > 0 } defaultRun)
        {
            return defaultRun;
        }

        return package.BinTargetNames switch
        {
            [var single] => single,
            // A package with no binary at all is a different mistake from an ambiguous one, and pointing the
            // user at WithCargoBinTarget would send them looking for a target that does not exist.
            [] => throw new DistributedApplicationException(
                $"Unable to work out which binary the Rust app '{resourceName}' produces: the package '{package.Name}' declares no " +
                $"binary targets. Point the app directory at a package with a binary, or select one with WithCargoPackage(\"<name>\")."),
            var many => throw new DistributedApplicationException(
                $"Unable to work out which binary the Rust app '{resourceName}' produces: the package '{package.Name}' declares " +
                $"{many.Count} binary targets. Call WithCargoBinTarget(\"<name>\") to select one.")
        };
    }

    private static CargoPackage ResolvePackage(CargoMetadata metadata, string? requestedPackage, string resourceName)
    {
        if (requestedPackage is not null)
        {
            // Reported here rather than left to cargo because this runs before any build: the debugger needs
            // the executable path up front, so a typo would otherwise surface as an unexplained
            // "Sequence contains no matching element" from LINQ.
            return metadata.Packages.FirstOrDefault(p => p.Name == requestedPackage)
                ?? throw new DistributedApplicationException(
                    $"The Rust app '{resourceName}' requested the cargo package '{requestedPackage}' with WithCargoPackage, but " +
                    $"'cargo metadata' reported no such package. Available packages: {FormatPackageNames(metadata)}.");
        }

View on GitHub (pinned to 25830f84bd)