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
- Call WithMavenBuild(...) or WithGradleBuild(...) on the AddJavaApp resource to choose the build tool explicitly.
- If you use goal/task-level APIs, call WithMavenGoal(...) or WithGradleTask(...) which also disambiguates.
- Delete the stale build files for the toolchain you no longer use (e.g. remove pom.xml from a Gradle project).
- 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
- Always declare WithMavenBuild/WithGradleBuild (or WithMavenGoal/WithGradleTask) on AddJavaApp resources instead of relying on detection.
- Delete stale build files after migrating between Maven and Gradle.
- Keep one toolchain's files per project directory in monorepos.
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
- The Java AppHost project in
- Java application ' ' has no wrapper at ' '. That path came…
- Java application ' ' has no in ' ' or in the build root…
- ArgumentOutOfRangeException: Specified argument was out of…
- Directory ' ' contains no pom.xml, build.gradle…
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> thatView on GitHub (pinned to 25830f84bd)