microsoft/aspire · error · InvalidOperationException

cannot be used when the application is already configured…

Error message

{methodName} cannot be used when the application is already configured to launch with {existing.Tool}. A Java application is launched by a single build tool.

What it means

A Java application is launched by exactly one build tool. If WithBuildToolLaunch detects an existing JavaBuildToolAnnotation whose Tool differs from the requested tool, it throws to prevent two competing launch configurations. This guards against, e.g., configuring Gradle as the launcher after Maven was already set.

Solutions

  1. Remove the earlier WithMavenGoal or WithGradleTask call so only one launch tool remains
  2. Change the new call to match the already-configured tool (e.g. use WithMavenGoal instead of WithGradleTask)
  3. Inspect the resource annotations to find which tool was configured first and keep that one

Example fix

// before
var java = builder.AddJavaApp("app", dir).WithMavenGoal("spring-boot:run").WithGradleTask("bootRun");
// after
var java = builder.AddJavaApp("app", dir).WithGradleTask("bootRun");
Defensive patterns

Strategy: validation

Validate before calling

if (builder.Resource.TryGetLastAnnotation<JavaBuildToolAnnotation>(out var t) && t.Tool != JavaBuildTool.Gradle)
{
    throw new InvalidOperationException("Launch already configured with a different build tool.");
}

Type guard

builder.Resource.TryGetLastAnnotation<JavaBuildToolAnnotation>(out var existingTool)

Try / catch

try { java.WithGradleTask("bootRun"); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already configured to launch with"))
{
    // keep only one launch tool
}

Prevention

When it happens

Trigger: Calling WithGradleTask on a resource that already has a Maven launch configured (or vice versa) via WithMavenGoal/WithGradleTask.

Common situations: Migrating a project from Maven to Gradle (or back) without removing the previous launch call; combining sample code from different sources that use different build tools.

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/21b57749a03d29f1. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Java/JavaHostingExtensions.cs:700

        this IResourceBuilder<T> builder,
        JavaBuildTool tool,
        string goalOrTask,
        string[] args,
        string methodName) where T : JavaAppResource
    {
        // A prebuilt JAR and a build-tool launch are mutually exclusive: the build tool decides what to
        // run, so -jar would be ignored. CommunityToolkit rejects both combinations; this port only
        // rejected the Gradle half, letting a Maven+JAR application silently drop its JAR.
        if (builder.Resource.HasAnnotationOfType<JavaJarPathAnnotation>())
        {
            throw new InvalidOperationException(
                $"{methodName} cannot be used when a JAR path has been specified. Use either the " +
                $"{nameof(AddJavaApp)} overload that takes a jarPath, or {methodName}, not both.");
        }

        if (builder.Resource.TryGetLastAnnotation<JavaBuildToolAnnotation>(out var existing) && existing.Tool != tool)
        {
            throw new InvalidOperationException(
                $"{methodName} cannot be used when the application is already configured to launch with " +
                $"{existing.Tool}. A Java application is launched by a single build tool.");
        }

        if (builder.Resource.TryGetLastAnnotation<JavaBuildStepAnnotation>(out var buildStep) && buildStep.Tool != tool)
        {
            throw new InvalidOperationException(
                $"{methodName} cannot be used when the application is already configured to build with " +
                $"{buildStep.Tool}. A Java application is built and launched by a single build tool.");
        }

        builder.WithAnnotation(
            new JavaBuildToolAnnotation(tool, args.Length > 0 ? [goalOrTask, .. args] : [goalOrTask]),
            ResourceAnnotationMutationBehavior.Replace);

        // The launch goal now compiles the application, so the build resource is redundant — unless
        // something outside the launch goal needs the build's output before the application starts.
        if (buildStep is not null

View on GitHub (pinned to 25830f84bd)