microsoft/aspire · error · InvalidOperationException

Cargo arguments for resource

Error message

Cargo arguments for resource '{resource.Name}' have not been resolved yet. The debug launch configuration must be created after the resource's arguments are evaluated.

What it means

WithVSCodeDebugging generates a debug launch configuration from resource.ResolvedCargoArgs, which DCP populates after resolving the resource's arguments. If the launch-configuration producer runs before that resolution, the property is null and this InvalidOperationException is thrown — mirroring the launch tool args check but for the debug path.

Solutions

  1. Let DCP resolve resource arguments before fetching the launch configuration; do not invoke the producer early.
  2. Verify the resource was started via the normal run/debug flow (F5/debugger attach after resource start).
  3. Check for and update mismatched Aspire package versions that could reorder DCP callback execution.
  4. In tests, evaluate the resource's arguments (set ResolvedCargoArgs) before calling the launch config producer.
Defensive patterns

Strategy: try-catch

Try / catch

try { await GetLaunchConfigurationAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("debug launch configuration must be created after")) {
    logger.LogError("Wait for DCP to resolve resource arguments before fetching the debug config");
}

Prevention

When it happens

Trigger: Requesting the VS Code launch configuration callback before the resource's arguments have been evaluated, e.g. custom tooling that enumerates launch configurations eagerly, or a lifecycle ordering issue during debug session startup.

Common situations: Editor tooling invoking the config producer early; tests calling the callback directly; Aspire version mismatches between CLI/dashboard and hosting library changing DCP ordering.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Rust/RustHostingExtensions.cs:651

        return candidate.StartsWith(prefix, StringComparison.Ordinal);
    }

    [Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
    internal static IResourceBuilder<T> WithVSCodeDebugging<T>(this IResourceBuilder<T> builder)
        where T : RustAppResource
    {
        ArgumentNullException.ThrowIfNull(builder);

        return builder.WithDebugSupport(
            async context =>
            {
                // DCP resolves the resource's arguments before it asks for the launch configuration
                // (ExecutableCreator.CreateObjectAsync builds the args, then invokes this producer),
                // so the resolved cargo arguments are reused here. That keeps the debug build identical
                // to the run command and means user cargo argument callbacks run exactly once per launch.
                var resource = (RustAppResource)context.Resource;
                var cargoArgs = resource.ResolvedCargoArgs
                    ?? throw new InvalidOperationException(
                        $"Cargo arguments for resource '{resource.Name}' have not been resolved yet. " +
                        "The debug launch configuration must be created after the resource's arguments are evaluated.");

                var workingDirectory = Path.GetFullPath(resource.WorkingDirectory);
                var executablePath = await ResolveDebugExecutablePathAsync(
                    resource,
                    workingDirectory,
                    builder.ApplicationBuilder.ExecutionContext,
                    context.EnvironmentVariables,
                    context.CancellationToken).ConfigureAwait(false);

                return new RustLaunchConfiguration
                {
                    Mode = context.Mode,
                    WorkingDirectory = workingDirectory,
                    Cargo = new RustCargoLaunchTarget
                    {
                        // The same cargo arguments run mode uses, so any target selection the user made

View on GitHub (pinned to 25830f84bd)