{"record":{"id":"0b7118e16b7c9fc4","repo":"microsoft/aspire","slug":"the-executable-launch-recipe-for-resource-resource-name","errorCode":null,"errorMessage":"The executable launch recipe for resource '{resource.Name}' returned a {plan.Mechanism} plan after {decision.Mechanism} was selected.","messagePattern":"The executable launch recipe for resource '(.+?)' returned a (.+?) plan after (.+?) was selected\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Dcp/ExecutableCreator.cs","lineNumber":146,"sourceCode":"        {\n            throw new InvalidOperationException(\n                $\"Resource '{resource.Name}' must have exactly one executable launch recipe, but {recipes.Length} were found.\");\n        }\n\n        var decision = launchPolicy.Decide(resource);\n        var context = new ExecutableLaunchContext(\n            resource,\n            configuration,\n            distributedApplicationOptions,\n            executionConfiguration,\n            decision,\n            resourceLogger,\n            cancellationToken);\n        var plan = await recipes[0].Recipe.CreateLaunchPlanAsync(context).ConfigureAwait(false);\n\n        if (plan.Mechanism != decision.Mechanism)\n        {\n            throw new InvalidOperationException(\n                $\"The executable launch recipe for resource '{resource.Name}' returned a {plan.Mechanism} plan after {decision.Mechanism} was selected.\");\n        }\n\n        if (plan.Mechanism == ExecutableLaunchMechanism.Ide && plan.LaunchConfigurations.Count == 0)\n        {\n            throw new InvalidOperationException(\n                $\"The executable launch recipe for resource '{resource.Name}' selected IDE execution without producing a launch configuration.\");\n        }\n\n        return plan;\n    }\n\n    internal static void Render(\n        RenderedModelResource<Executable> renderedResource,\n        ExecutableLaunchPlan plan,\n        ExecutablePemCertificates? pemCertificates,\n        ILogger logger)\n    {","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Dcp/ExecutableCreator.cs#L128-L164","documentation":"The launch policy makes an up-front decision (e.g., Ide or Process) about the launch mechanism, and the recipe's CreateLaunchPlanAsync must honor it. When the produced plan's Mechanism differs from the selected decision.Mechanism, this InvalidOperationException is thrown — a contract violation between the policy and the recipe implementation.","triggerScenarios":"A custom or buggy ExecutableLaunchRecipeAnnotation recipe whose CreateLaunchPlanAsync returns a plan with a different ExecutableLaunchMechanism than the one the launch policy decided (e.g., policy selected Ide but recipe returned Process).","commonSituations":"Custom launch recipes that ignore the decision context; integration packages with incompatible recipe implementations; switching run modes (Run vs publish/IDE attach) with a recipe not honoring the mechanism.","solutions":["Fix the recipe implementation so CreateLaunchPlanAsync returns a plan whose Mechanism matches context/decision.Mechanism","Remove or replace the custom launch recipe annotation with the standard one for the resource type","Check integration package versions for a known fix and upgrade Aspire.Hosting/integrations together"],"exampleFix":"// before (custom recipe)\nreturn new ExecutableLaunchPlan { Mechanism = ExecutableLaunchMechanism.Process, ... }; // policy chose Ide\n// after\nreturn new ExecutableLaunchPlan { Mechanism = decision.Mechanism, ... };","handlingStrategy":"validation","validationCode":"var decision = launchPolicy.Decide(resource);\nvar context = new ExecutableLaunchContext(resource, decision, resourceLogger, cancellationToken);\nvar plan = await recipe.CreateLaunchPlanAsync(context);\nif (plan.Mechanism != decision.Mechanism)\n    throw new InvalidOperationException(\"Recipe returned a mismatched launch mechanism.\");","typeGuard":"bool MechanismMatches(ExecutableLaunchPlan p, LaunchDecision d) => p.Mechanism == d.Mechanism;","tryCatchPattern":"try\n{\n    await creator.CreateObjectAsync(renderedResource, resourceLogger, ct);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"plan after\"))\n{\n    // Recipe/policy contract violation — fix or replace the custom launch recipe.\n}","preventionTips":["Custom recipes must derive the plan mechanism from the decision, not hardcode it","Unit-test custom recipes against every ExecutableLaunchMechanism the policy can select","Avoid recipes that ignore ExecutableLaunchContext/decision inputs"],"tags":["launch","mechanism","recipe","dcp"],"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-21T09:17:21.228Z"}