microsoft/aspire · error

Directory ' ' contains both Maven and Gradle build files…

Error message

Directory '{appDirectory}' contains both Maven and Gradle build files, so the build tool for resource '{resourceName}' is ambiguous. Use AddJavaApp and call WithMavenBuild, WithGradleBuild, WithMavenGoal, or WithGradleTask to choose one explicitly.

What it means

JavaBuildToolResolver.Detect infers whether a Java app directory is Maven- or Gradle-based by looking for build files (pom.xml vs build.gradle/build.gradle.kts with settings files). When both toolchains' files are present the choice is ambiguous, and rather than guessing (which historically caused run and publish to disagree), it throws and asks the author to declare the tool explicitly. The resolver intentionally rejects ambiguous directories instead of silently picking one.

Solutions

  1. Call WithMavenBuild(...) or WithGradleBuild(...) on the AddJavaApp resource to choose the build tool explicitly.
  2. If you use goal/task-level APIs, call WithMavenGoal(...) or WithGradleTask(...) which also disambiguates.
  3. Delete the stale build files for the toolchain you no longer use (e.g. remove pom.xml from a Gradle project).
  4. Move each project's build files into its own directory so appDirectory contains only one toolchain's files.

Example fix

// before
builder.AddJavaApp("api", "../api"); // directory has pom.xml AND build.gradle.kts -> throws

// after
builder.AddJavaApp("api", "../api")
       .WithGradleBuild(); // explicit choice resolves the ambiguity
Defensive patterns

Strategy: validation

Validate before calling

// before calling AddJavaApp, ensure only one toolchain's files exist
var hasMaven = Directory.EnumerateFiles(appDirectory, "pom.xml", SearchOption.TopDirectoryOnly).Any();
var hasGradle = Directory.EnumerateFiles(appDirectory, "build.gradle*", SearchOption.TopDirectoryOnly).Any();
if (hasMaven && hasGradle) throw new InvalidOperationException($"{appDirectory} has both Maven and Gradle files; remove one or call WithMavenBuild/WithGradleBuild.");

Try / catch

try {
  var app = builder.AddJavaApp("api", "../api");
} catch (InvalidOperationException ex) when (ex.Message.Contains("ambiguous")) {
  // choose the build tool explicitly via WithMavenBuild/WithGradleBuild and retry
}

Prevention

When it happens

Trigger: Adding a Java app whose appDirectory contains both a pom.xml and a Gradle build file (build.gradle/build.gradle.kts/settings.gradle) while using AddJavaApp without calling WithMavenBuild, WithGradleBuild, WithMavenGoal, or WithGradleTask.

Common situations: Repositories migrated from Maven to Gradle (or vice versa) where the old pom.xml was left behind; monorepo sample directories containing multiple build systems; generated scaffolding that emits both files; copying a Gradle wrapper into a Maven project.

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

Appendix: source

Thrown at src/Aspire.Hosting.Java/JavaBuildToolResolver.cs:39

    /// <summary>
    /// Returns the build tool declared by files in <paramref name="appDirectory"/>, or
    /// <see langword="null"/> when none is declared.
    /// </summary>
    internal static JavaBuildTool? Detect(
        string appDirectory,
        string resourceName,
        Func<string, Exception> createAmbiguityException)
    {
        var hasMaven = File.Exists(Path.Combine(appDirectory, "pom.xml"));
        var hasGradle = s_gradleBuildFileNames.Any(fileName => File.Exists(Path.Combine(appDirectory, fileName)));

        // Ambiguous projects are rejected rather than guessed. Maven-first detection made publish produce
        // a different artifact than run mode for the same directory, while an explicit build or launch API
        // records the author's choice for both paths.
        if (hasMaven && hasGradle)
        {
            throw createAmbiguityException(
                $"Directory '{appDirectory}' contains both Maven and Gradle build files, so the build tool for resource '{resourceName}' is ambiguous. " +
                "Use AddJavaApp and call WithMavenBuild, WithGradleBuild, WithMavenGoal, or WithGradleTask to choose one explicitly.");
        }

        return (hasMaven, hasGradle) switch
        {
            (true, false) => JavaBuildTool.Maven,
            (false, true) => JavaBuildTool.Gradle,
            _ => null
        };
    }

    /// <summary>
    /// Resolves the wrapper selected for a resource on the requested execution platform.
    /// </summary>
    /// <remarks>
    /// The application's own directory wins, then the search walks up to the build root. A Gradle
    /// multi-project build has exactly one <c>gradlew</c>, next to the <c>settings.gradle</c> that

View on GitHub (pinned to 25830f84bd)