{"record":{"id":"ea7968fe0f52e915","repo":"apache/maven","slug":"recursive-build-requested-but-source-has-no-path","errorCode":null,"errorMessage":"Recursive build requested but source has no path","messagePattern":"Recursive build requested but source has no path","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java","lineNumber":817,"sourceCode":"            properties.putAll(request.getSystemProperties());\n            properties.putAll(request.getUserProperties());\n\n            return properties;\n        }\n\n        /**\n         * Convenience method for getting properties with profiles without additional base properties.\n         * This is a backward compatibility method that provides an empty base properties map.\n         */\n        private Map<String, String> getPropertiesWithProfiles(Model model) {\n            return getPropertiesWithProfiles(model, new HashMap<>());\n        }\n\n        private void buildBuildPom() throws ModelBuilderException {\n            // Retrieve and normalize the source path, ensuring it's non-null and in absolute form\n            Path top = request.getSource().getPath();\n            if (top == null) {\n                throw new IllegalStateException(\"Recursive build requested but source has no path\");\n            }\n            top = top.toAbsolutePath().normalize();\n\n            // Obtain the root directory, resolving it if necessary\n            Path rootDirectory;\n            try {\n                rootDirectory = session.getRootDirectory();\n            } catch (IllegalStateException e) {\n                rootDirectory = session.getService(RootLocator.class).findMandatoryRoot(top);\n            }\n\n            // Locate and normalize the root POM if it exists, fallback to top otherwise\n            Path root = modelProcessor.locateExistingPom(rootDirectory);\n            if (root != null) {\n                root = root.toAbsolutePath().normalize();\n            } else {\n                root = top;\n            }","sourceCodeStart":799,"sourceCodeEnd":835,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelBuilder.java#L799-L835","documentation":"buildBuildPom() implements recursive model building by walking the file system from the request's source up to the root POM (via session.getRootDirectory() / RootLocator.findMandatoryRoot). That walk needs a real Path; ModelSource implementations backed by a URL, a String, or an InputStream return null from getPath(), so the request fails fast with IllegalStateException.","triggerScenarios":"Requesting a recursive build while the ModelSource is non-file-based: e.g. request.setSource(new StringModelSource(pomXml)) or a URL-based source, which makes request.getSource().getPath() return null inside buildBuildPom().","commonSituations":"Embedding Maven (maven-embedder, IDE tooling, tests) and handing the builder an in-memory or remote pom; migrating from older APIs where the caller drove recursion from files itself.","solutions":["Write the pom to disk (or use the existing file) and pass a path-based Source so getPath() is non-null","Build non-recursively when the model can only come from memory or a URL","Locate the root pom yourself and pass that file's source for the recursive build"],"exampleFix":"// before: recursive build from an in-memory model\nrequest.setSource(new StringModelSource(pomXml));\nrequest.setRecursive(true);\n\n// after: recursive build from a real file\nPath pom = Path.of(projectDir, \"pom.xml\");\nrequest.setSource(Sources.buildSource(pom));\nrequest.setRecursive(true);","handlingStrategy":"validation","validationCode":"if (request.isRecursive() && request.getSource().getPath() == null) {\n    // non-file source cannot drive a recursive build\n    throw new IllegalArgumentException(\n        \"Recursive builds require a file-based ModelSource; got: \" + request.getSource().getClass().getName());\n}","typeGuard":null,"tryCatchPattern":"try {\n    result = modelBuilder.build(request);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"source has no path\")) {\n        // fall back to non-recursive build or write the model to a temp file first\n    } else throw e;\n}","preventionTips":["When embedding Maven, default to Path-based sources; only use String/URL sources for single-model (non-recursive) reads","Wrap remote or in-memory poms by materializing them into a temp directory when recursion is required"],"tags":["maven","model-building","embedding","file-system"],"backgroundTag":"missing-source-path","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}