microsoft/aspire · error · InvalidOperationException

Resource ' ' is already configured to launch with . A Java…

Error message

Resource '{builder.Resource.Name}' is already configured to launch with {launchTool.Tool}. A Java application is built and launched by a single build tool.

What it means

Build and launch must be driven by the same build tool. WithJavaBuildStep throws when the resource already has a JavaBuildToolAnnotation (set by WithMavenGoal/WithGradleTask) for a tool different from the one being configured for the build step.

Solutions

  1. Match the build step to the launch tool (e.g. call WithGradleBuild when the launch is WithGradleTask)
  2. Remove the launch call and reconfigure both build and launch with the same tool
  3. Decide on one build tool for the resource and use only its With* APIs

Example fix

// before
var java = builder.AddJavaApp("app", dir).WithGradleTask("bootRun").WithMavenBuild("package");
// after
var java = builder.AddJavaApp("app", dir).WithGradleTask("bootRun").WithGradleBuild("build");
Defensive patterns

Strategy: validation

Validate before calling

if (builder.Resource.TryGetLastAnnotation<JavaBuildToolAnnotation>(out var launch) && launch.Tool != JavaBuildTool.Maven)
{
    throw new InvalidOperationException("Build step tool must match the configured launch tool.");
}

Type guard

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

Try / catch

try { java.WithMavenBuild("package"); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already configured to launch with"))
{
    // use the build-step API for the same tool as the launch
}

Prevention

When it happens

Trigger: Calling WithMavenBuild on a resource whose launch was configured with WithGradleTask (or the Maven/Gradle reverse combination).

Common situations: Configuring the build step from one example and the launch goal from another that used a different build tool; partial migration between Maven and Gradle.

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

Appendix: source

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

    private static IResourceBuilder<T> WithJavaBuildStep<T>(
        this IResourceBuilder<T> builder,
        JavaBuildTool tool,
        string buildResourceName,
        string[] buildArgs)
        where T : JavaAppResource
    {
        // Building with both tools would produce two artifacts and leave the container build with no way
        // to choose between them, so it is rejected the same way conflicting launch modes are.
        if (builder.Resource.TryGetLastAnnotation<JavaBuildStepAnnotation>(out var existing) && existing.Tool != tool)
        {
            throw new InvalidOperationException(
                $"Resource '{builder.Resource.Name}' is already configured to build with {existing.Tool}. " +
                $"Call either WithMavenBuild or WithGradleBuild, not both.");
        }

        if (builder.Resource.TryGetLastAnnotation<JavaBuildToolAnnotation>(out var launchTool) && launchTool.Tool != tool)
        {
            throw new InvalidOperationException(
                $"Resource '{builder.Resource.Name}' is already configured to launch with {launchTool.Tool}. " +
                "A Java application is built and launched by a single build tool.");
        }

        // A launch goal such as spring-boot:run or bootRun compiles the application on its way to running
        // it, so a build resource in front of it would only repeat work. That holds only while the launch
        // goal is what actually starts the application and nothing else needs the build's output first.
        var createRunResource = builder.ApplicationBuilder.ExecutionContext.IsRunMode
            && (RequiresBuildBeforeLaunch(builder)
                || launchTool is null && !builder.Resource.HasAnnotationOfType<JavaDetectedBuildToolAnnotation>());

        // Recorded in every execution context: in publish mode there is no build-step resource, but the
        // generated Dockerfile still runs this tool and these arguments to produce the deployable JAR.
        builder.WithAnnotation(
            new JavaBuildStepAnnotation(
                createRunResource ? buildResourceName : null,
                tool,
                buildArgs),

View on GitHub (pinned to 25830f84bd)