{"record":{"id":"a158f4db8e4fb802","repo":"microsoft/aspire","slug":"resource-resource-name-must-have-exactly-one-executable","errorCode":null,"errorMessage":"Resource '{resource.Name}' must have exactly one executable launch recipe, but {recipes.Length} were found.","messagePattern":"Resource '(.+?)' must have exactly one executable launch recipe, but (.+?) were found\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Dcp/ExecutableCreator.cs","lineNumber":129,"sourceCode":"\n        await factory\n            .CreateDcpObjectsAsync([renderedResource.DcpResource], cancellationToken)\n            .ConfigureAwait(false);\n    }\n\n    internal static async Task<ExecutableLaunchPlan> ResolveLaunchPlanAsync(\n        IResource resource,\n        IExecutionConfigurationResult executionConfiguration,\n        IConfiguration configuration,\n        DistributedApplicationOptions distributedApplicationOptions,\n        ExecutableLaunchPolicy launchPolicy,\n        ILogger resourceLogger,\n        CancellationToken cancellationToken)\n    {\n        var recipes = resource.Annotations.OfType<ExecutableLaunchRecipeAnnotation>().ToArray();\n        if (recipes.Length != 1)\n        {\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.\");","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Dcp/ExecutableCreator.cs#L111-L147","documentation":"Every executable resource must carry exactly one ExecutableLaunchRecipeAnnotation that describes how to launch it. ResolveLaunchPlanAsync throws this InvalidOperationException when the annotation count is not exactly one (zero or multiple), because the launch plan is ambiguous or missing.","triggerScenarios":"Resolving the launch plan for a resource whose Annotations contain zero ExecutableLaunchRecipeAnnotation (e.g., the resource type forgot to add it) or more than one (conflicting annotations added twice).","commonSituations":"Custom resource types built without calling the standard annotation setup; a resource builder accidentally adding the launch recipe annotation twice; version mismatch between an integration package and Aspire.Hosting.","solutions":["Check how the resource is created and ensure exactly one ExecutableLaunchRecipeAnnotation is added","Search the model annotations for duplicates if your code adds the annotation manually","Update integration packages to versions compatible with your Aspire.Hosting version"],"exampleFix":"// before (annotation added twice)\nresource.WithAnnotation(new ExecutableLaunchRecipeAnnotation { ... });\nresource.WithAnnotation(new ExecutableLaunchRecipeAnnotation { ... });\n// after\nresource.WithAnnotation(new ExecutableLaunchRecipeAnnotation { ... });","handlingStrategy":"validation","validationCode":"var recipes = resource.Annotations.OfType<ExecutableLaunchRecipeAnnotation>().ToArray();\nif (recipes.Length != 1)\n{\n    throw new InvalidOperationException($\"{resource.Name} must have exactly one ExecutableLaunchRecipeAnnotation, found {recipes.Length}.\");\n}","typeGuard":"bool HasSingleLaunchRecipe(IResource r) => r.Annotations.Count(a => a is ExecutableLaunchRecipeAnnotation) == 1;","tryCatchPattern":"try\n{\n    await creator.CreateObjectAsync(renderedResource, resourceLogger, ct);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"exactly one executable launch recipe\"))\n{\n    // Inspect resource annotations; add or de-duplicate the launch recipe annotation.\n}","preventionTips":["Always add exactly one ExecutableLaunchRecipeAnnotation in custom resource builders","Audit builders for accidental duplicate annotation calls","Keep integration packages in sync with Aspire.Hosting versions"],"tags":["annotations","launch","recipe","dcp"],"backgroundTag":"missing-required-argument","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"}