{"record":{"id":"0b96a63dbf41e296","repo":"microsoft/aspire","slug":"java-application-resource-name-has-no-wrapper-at-wrapperpath","errorCode":null,"errorMessage":"Java application '{resource.Name}' has no wrapper at '{wrapperPath}'. That path came from WithWrapperPath and is resolved relative to the application's working directory '{resource.WorkingDirectory}'.","messagePattern":"Java application '(.+?)' has no wrapper at '(.+?)'\\. That path came from WithWrapperPath and is resolved relative to the application's working directory '(.+?)'\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Java/JavaHostingExtensions.cs","lineNumber":1537,"sourceCode":"    /// Throws when the wrapper the resource will launch is not on disk.\n    /// </summary>\n    /// <remarks>\n    /// Deferred to resource start so that the whole AppHost has been authored first: only then is it\n    /// known whether a <see cref=\"WithWrapperPath{T}(IResourceBuilder{T}, string)\"/> override supplied\n    /// the wrapper that the default location lacks.\n    /// </remarks>\n    private static void ValidateWrapperExists(JavaAppResource resource, JavaBuildTool tool)\n    {\n        var wrapperPath = JavaBuildToolResolver.ResolveWrapperPath(resource, tool, OperatingSystem.IsWindows());\n\n        if (File.Exists(wrapperPath))\n        {\n            return;\n        }\n\n        if (resource.HasAnnotationOfType<WrapperAnnotation>())\n        {\n            throw new DistributedApplicationException(\n                $\"Java application '{resource.Name}' has no wrapper at '{wrapperPath}'. That path came \" +\n                $\"from {nameof(WithWrapperPath)} and is resolved relative to the application's working \" +\n                $\"directory '{resource.WorkingDirectory}'.\");\n        }\n\n        var wrapperName = JavaBuildToolResolver.GetDefaultWrapperName(tool, OperatingSystem.IsWindows());\n\n        throw new DistributedApplicationException(\n            $\"Java application '{resource.Name}' has no {wrapperName} in '{resource.WorkingDirectory}' \" +\n            $\"or in the build root above it. Aspire runs Java applications through the project's own \" +\n            $\"wrapper so that every build uses the tool version the repository pins. Generate one with \" +\n            $\"{GenerateWrapperCommand(tool)}, or point at an existing wrapper with {nameof(WithWrapperPath)}.\");\n    }\n\n    /// <summary>\n    /// Arranges for the resource's wrapper to be validated once its configuration is final.\n    /// </summary>\n    private static IResourceBuilder<T> WithDeferredWrapperValidation<T>(","sourceCodeStart":1519,"sourceCodeEnd":1555,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Java/JavaHostingExtensions.cs#L1519-L1555","documentation":"WithWrapperPath let the user point at a custom build-tool wrapper, but the wrapper file does not exist at the given location. ValidateWrapperExists throws a DistributedApplicationException stating that the path came from WithWrapperPath and is resolved relative to the application's working directory.","triggerScenarios":"Calling WithWrapperPath(\"some/path/mvnw\") where no file exists at workingDirectory/some/path/mvnw; validation runs via WithDetectedBuildTool or deferred wrapper validation.","commonSituations":"Typo or wrong casing in the wrapper path; passing an absolute path when resolution is relative to WorkingDirectory; the wrapper file was gitignored or not copied into the build context; Windows/macOS path-separator mistakes.","solutions":["Fix the path passed to WithWrapperPath so it points at the existing wrapper relative to the resource's working directory","Move or restore the wrapper script (mvnw/mvnw.cmd or gradlew/gradlew.bat) into the expected location","Remove WithWrapperPath to fall back to the default wrapper resolution from the working directory or build root"],"exampleFix":"// before\n.AddJavaApp(\"app\", dir).WithWrapperPath(\"tools/mvnw\") // file not there\n// after\n.AddJavaApp(\"app\", dir).WithWrapperPath(\"mvnw\") // wrapper sits directly in the working directory","handlingStrategy":"validation","validationCode":"var wrapperPath = Path.GetFullPath(Path.Combine(workingDirectory, relativeWrapperPath));\nif (!File.Exists(wrapperPath))\n{\n    throw new FileNotFoundException($\"Wrapper not found at {wrapperPath}; fix the WithWrapperPath argument.\");\n}","typeGuard":"bool WrapperExists(string workingDir, string relPath) => File.Exists(Path.Combine(workingDir, relPath));","tryCatchPattern":"try { ConfigureJavaApp(); }\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"has no wrapper at\"))\n{\n    // fix the WithWrapperPath value or restore the wrapper file\n}","preventionTips":["Pass WithWrapperPath values relative to the resource's working directory","Commit wrapper scripts to the repository and verify they exist in CI","Check file existence with File.Exists before configuring a custom wrapper"],"tags":["java","file-not-found","wrapper","maven","gradle"],"backgroundTag":"file-not-found","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}