{"record":{"id":"47d2900a93c11251","repo":"microsoft/aspire","slug":"cargo-arguments-for-resource-resource-name-have-not-been","errorCode":null,"errorMessage":"Cargo arguments for resource '{resource.Name}' have not been resolved yet. The launch tool arguments must be created after the resource's arguments are evaluated.","messagePattern":"Cargo arguments for resource '(.+?)' have not been resolved yet\\. The launch tool arguments must be created after the resource's arguments are evaluated\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Rust/RustHostingExtensions.cs","lineNumber":111,"sourceCode":"            .WithRustDefaults()\n            .WithCargoArgs(context => AddInitialCargoArgs(resource, builder.ExecutionContext, context.Args))\n            .WithArgs(async context =>\n            {\n                // Resolve the cargo arguments once and record them: the debug launch configuration\n                // reuses this list rather than invoking the user's callbacks a second time.\n                var cargoArgs = new List<string>();\n\n                foreach (var annotation in resource.Annotations.OfType<RustCargoArgsCallbackAnnotation>())\n                {\n                    await annotation.Callback(new RustCargoArgsCallbackContext(resource, cargoArgs, context.CancellationToken)).ConfigureAwait(false);\n                }\n\n                resource.ResolvedCargoArgs = cargoArgs;\n            })\n            .WithLaunchToolArgs(context =>\n            {\n                var cargoArgs = resource.ResolvedCargoArgs\n                    ?? throw new InvalidOperationException(\n                        $\"Cargo arguments for resource '{resource.Name}' have not been resolved yet. \" +\n                        \"The launch tool arguments must be created after the resource's arguments are evaluated.\");\n\n                // No validation is performed on these arguments: every value is passed through raw for\n                // cargo itself to accept or reject. Nothing here inspects what they contain, so only the\n                // WithCargo* options feed the executable-path and Dockerfile resolution — a flag that\n                // arrives as a raw string through WithCargoArgs is not parsed back out. Doing so would be\n                // a second, subtly-different implementation of cargo's own argument handling that could\n                // never be complete, since a WithArgs callback can append arguments after this point.\n                context.Args.Add(\"run\");\n                foreach (var cargoArg in cargoArgs)\n                {\n                    context.Args.Add(cargoArg);\n                }\n\n                context.Args.Add(\"--\");\n            }, ownedByLaunchConfigurationType: \"rust\")\n            .WithVSCodeDebugging()","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Rust/RustHostingExtensions.cs#L93-L129","documentation":"AddRustApp registers a WithLaunchToolArgs callback that reads resource.ResolvedCargoArgs. That value is populated by an earlier callback that resolves the resource's parameterized arguments. If the launch-tool callback runs before the resolution callback, ResolvedCargoArgs is still null and this InvalidOperationException is thrown.","triggerScenarios":"The launch tool args factory is invoked out of order — e.g. custom code or a callback ordering change causes WithLaunchToolArgs's lambda to execute before the argument-resolution callback that assigns ResolvedCargoArgs.","commonSituations":"Customizing the Rust resource with additional callbacks that run launch tool arg creation early; calling APIs that force launch-config generation before argument evaluation; version upgrades that changed callback ordering.","solutions":["Ensure any custom callbacks that need cargo args run after argument evaluation (DistributedApplicationEventing / callback registration order).","Do not invoke WithLaunchToolArgs-equivalent producers manually; let DCP drive the normal lifecycle.","If reproducing in a test, call the resource's argument evaluation step before requesting launch tool args.","Upgrade to a version where the ordering bug (if in the library) is fixed and file a repro if it persists."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before consuming launch tool args\nvar resolved = resource.GetType().GetProperty(\"ResolvedCargoArgs\")?.GetValue(resource) as string[];\nif (resolved is null) throw new InvalidOperationException(\"Evaluate resource arguments before requesting launch tool args\");","typeGuard":null,"tryCatchPattern":"try { BuildLaunchToolArgs(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"have not been resolved yet\")) {\n    logger.LogError(\"Ensure argument evaluation runs before launch tool arg creation\");\n}","preventionTips":["Do not reorder AddRustApp's internal callbacks","Avoid manually invoking launch-config producers","Pin Aspire package versions to avoid ordering changes across upgrades"],"tags":["lifecycle","callbacks","rust","state"],"backgroundTag":"invalid-state-transition","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"}