microsoft/aspire · error · DistributedApplicationException
Java application ' ' cannot be published because its…
Error message
Java application '{resource.Name}' cannot be published because its wrapper '{resolvedWrapperPath}' is outside the build context '{appDirectory}'. Move the wrapper into the application directory, or set the build context to a directory that contains both. What it means
Aspire's Java Dockerfile generator throws this when the resolved wrapper script (mvnw/gradlew) for a Java app resource resolves outside the Docker build context directory (appDirectory). The Dockerfile must COPY the wrapper from the build context, so a path escaping it (or an absolute path) cannot be expressed. This is a publish-time configuration validation to fail early instead of producing a broken image build.
Solutions
- Move the wrapper script (mvnw/gradlew) into the Java application directory used as the build context.
- Change the build context (the directory passed to AddJavaApp) so it contains both the app sources and the wrapper.
- Point WithWrapperPath at a wrapper that already exists inside the app directory.
Example fix
// before
builder.AddJavaApp("api", "src/Api")
.WithWrapperPath("../mvnw");
// after
builder.AddJavaApp("api", ".")
.WithWrapperPath("src/Api/mvnw"); Defensive patterns
Strategy: validation
Validate before calling
var wrapper = "src/Api/mvnw";
var context = "src/Api";
var rel = Path.GetRelativePath(context, wrapper);
if (rel.StartsWith("../") || Path.IsPathRooted(rel))
throw new Exception("Wrapper must be inside the build context"); Try / catch
try { /* publish */ }
catch (DistributedApplicationException ex) when (ex.Message.Contains("outside the build context"))
{ /* move wrapper or change context, then republish */ } Prevention
- Keep mvnw/gradlew committed inside the Java project directory
- Never reference wrappers from parent or sibling directories
- Pass the project root containing both sources and wrapper to AddJavaApp
When it happens
Trigger: Calling aspire publish (or generating a Dockerfile) for an AddJavaApp resource whose wrapper — set via WithWrapperPath or the default lookup — resolves to a path outside the app's directory, e.g. '../mvnw' relative path or an absolute path on another root.
Common situations: Pointing WithWrapperPath at a shared wrapper in a parent or sibling repo directory; the app directory being a subfolder of the solution while the wrapper lives at the repo root; Windows absolute wrapper paths mixed with Linux context assumptions.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Java application ' ' cannot be published because its…
- DockerfileBuildAnnotation should exist after calling…
- Generated Deno Dockerfiles do not support
- Java application ' ' cannot be published because it uses…
- Java application ' ' cannot be published because its…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/08666d07b36612b5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Java/JavaDockerfileGenerator.cs:1045
/// <para>
/// The wrapper also has to sit inside the build context, because only files under the context are
/// uploaded to the daemon and reachable by <c>COPY . .</c>. A wrapper outside it exists on the host
/// and not in the image, so the build would fail partway through with an opaque "not found".
/// </para>
/// </remarks>
/// <exception cref="DistributedApplicationException">No wrapper is present, or the configured wrapper is outside the build context.</exception>
private static string ResolveWrapperForContext(JavaAppResource resource, string appDirectory, JavaBuildTool tool)
{
// Container builds execute on Linux even when publish runs on Windows. Passing that platform
// to the shared resolver keeps the naming rule identical to run mode without selecting a batch
// script that the build stage cannot execute.
var resolvedWrapperPath = JavaBuildToolResolver.ResolveWrapperPath(resource, tool, isWindows: false);
var isConfigured = resource.HasAnnotationOfType<WrapperAnnotation>();
var relative = Path.GetRelativePath(appDirectory, resolvedWrapperPath).Replace('\\', '/');
if (relative.StartsWith("../", StringComparison.Ordinal) || IsPathRootedOnAnyPlatform(relative))
{
throw new DistributedApplicationException(
$"Java application '{resource.Name}' cannot be published because its wrapper " +
$"'{resolvedWrapperPath}' is outside the build context '{appDirectory}'. " +
"Move the wrapper into the application directory, or set the build context to a " +
"directory that contains both.");
}
if (!File.Exists(resolvedWrapperPath))
{
if (isConfigured)
{
throw new DistributedApplicationException(
$"Java application '{resource.Name}' cannot be published because the wrapper " +
$"configured with WithWrapperPath was not found at '{resolvedWrapperPath}'.");
}
var defaultWrapperName = JavaBuildToolResolver.GetDefaultWrapperName(tool, isWindows: false);
throw new DistributedApplicationException(
$"Java application '{resource.Name}' cannot be published because there is no " +View on GitHub (pinned to 25830f84bd)