{"record":{"id":"a5f65b12e1e6f2b3","repo":"apache/maven","slug":"the-pom-found-does-not-belong-to-the-given-directo","errorCode":null,"errorMessage":"The POM found does not belong to the given directory: ${pom}","messagePattern":"The POM found does not belong to the given directory: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java","lineNumber":92,"sourceCode":"    @Inject\n    public DefaultModelProcessor(ModelXmlFactory modelXmlFactory, @Nullable Map<String, ModelParser> modelParsers) {\n        this.modelXmlFactory = modelXmlFactory;\n        this.modelParsers = modelParsers;\n    }\n\n    @Override\n    public Path locateExistingPom(Path projectDirectory) {\n        // Note that the ModelProcessor#locatePom never returns null\n        // while the ModelParser#locatePom needs to return an existing path!\n        Path pom = modelParsers.values().stream()\n                .map(m -> m.locate(projectDirectory)\n                        .map(org.apache.maven.api.services.Source::getPath)\n                        .orElse(null))\n                .filter(Objects::nonNull)\n                .findFirst()\n                .orElseGet(() -> doLocateExistingPom(projectDirectory));\n        if (pom != null && !pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {\n            throw new IllegalArgumentException(\"The POM found does not belong to the given directory: \" + pom);\n        }\n        return pom;\n    }\n\n    @Override\n    public Model read(XmlReaderRequest request) throws IOException {\n        Objects.requireNonNull(request, \"source cannot be null\");\n        Path pomFile = request.getPath();\n        if (pomFile != null) {\n            Path projectDirectory = pomFile.getParent();\n            Map<String, ModelParserException> exceptions = new LinkedHashMap<>();\n            for (Map.Entry<String, ModelParser> parser : modelParsers.entrySet()) {\n                try {\n                    Optional<Model> model = parser.getValue()\n                            .locateAndParse(projectDirectory, Map.of(ModelParser.STRICT, request.isStrict()));\n                    if (model.isPresent()) {\n                        return model.get().withPomFile(pomFile);\n                    }","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java#L74-L110","documentation":"DefaultModelProcessor.locateExistingPom(Path projectDirectory) asks every registered ModelParser (the standard pom.xml parser plus any polyglot extensions) to find a build file for the directory. The result must be the directory itself or a direct child of it; if a parser returns a path outside the directory, IllegalArgumentException is thrown to stop a parser from escaping the project directory.","triggerScenarios":"A polyglot or custom ModelParser whose locate(projectDirectory) resolves to a build file in a parent or sibling directory (e.g. a Gradle/BND file up the tree), so pom.getParent() differs from projectDirectory.","commonSituations":"polyglot-maven extensions declared in .mvn/extensions.xml; in-house ModelParser implementations that search upwards instead of only inside the given directory; symlinked checkouts where resolution leaves the module tree.","solutions":["Inspect .mvn/extensions.xml (and any core extensions in settings) for polyglot parsers and disable or update the offending one","Fix the custom ModelParser.locate so it only ever returns a file inside the given directory","Call locateExistingPom with the directory that actually contains the build file"],"exampleFix":"// before: parser escapes the directory\npublic Optional<Source> locate(Path dir) {\n    return Optional.of(buildSource(dir.getParent().resolve(\"build.gradle\")));\n}\n\n// after: only look inside the directory\npublic Optional<Source> locate(Path dir) {\n    Path f = dir.resolve(\"build.gradle\");\n    return Files.isRegularFile(f) ? Optional.of(buildSource(f)) : Optional.empty();\n}","handlingStrategy":"validation","validationCode":"Path pom = modelProcessor.locateExistingPom(projectDirectory);\n// post-condition, mirrors the guard in locateExistingPom\nif (pom != null && !pom.equals(projectDirectory) && !pom.getParent().equals(projectDirectory)) {\n    throw new IllegalArgumentException(\"Located pom escapes the project directory: \" + pom);\n}","typeGuard":null,"tryCatchPattern":"try {\n    Path pom = modelProcessor.locateExistingPom(dir);\n} catch (IllegalArgumentException e) {\n    // an extension parser claimed a build file outside dir; disable polyglot extensions and retry\n}","preventionTips":["Keep polyglot/extension ModelParsers strictly scoped: locate() must only return files inside the given directory","Pin extension versions in .mvn/extensions.xml so a parser behavior change cannot surprise the build","Add a unit test for custom parsers asserting the returned path's parent equals the input directory"],"tags":["maven","polyglot","model-processor","extensions"],"backgroundTag":"invalid-pom-location","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}