apache/maven · error · IllegalStateException

Unable to find the root directory. Create a .mvn directory i

Error message

Unable to find the root directory. Create a .mvn directory in the root directory or add the root="true" attribute on the root project's model to identify it.

What it means

IllegalStateException from MavenExecutionRequest.getRootDirectory() when the request was never given a root directory. Maven locates the root of a multi-module build by scanning upward for a .mvn directory or a pom with root="true"; DefaultMavenExecutionRequest only stores the result and throws this constant message (RootLocator.UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE) if nothing was found and no value was set.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java:1171

        return this;
    }

    @Deprecated
    @Override
    public void setMultiModuleProjectDirectory(File directory) {
        this.multiModuleProjectDirectory = directory;
    }

    @Deprecated
    @Override
    public File getMultiModuleProjectDirectory() {
        return multiModuleProjectDirectory;
    }

    @Override
    public Path getRootDirectory() {
        if (rootDirectory == null) {
            throw new IllegalStateException(RootLocator.UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE);
        }
        return rootDirectory;
    }

    @Override
    public MavenExecutionRequest setRootDirectory(Path rootDirectory) {
        this.rootDirectory = rootDirectory;
        return this;
    }

    @Override
    public Path getTopDirectory() {
        return topDirectory;
    }

    @Override
    public MavenExecutionRequest setTopDirectory(Path topDirectory) {
        this.topDirectory = topDirectory;

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Create a .mvn directory at the repository root (an empty one is enough)
  2. Or mark the root pom with <project ... root="true">
  3. When building requests programmatically, call request.setRootDirectory(Paths.get(...)) before anything reads it, or run the request through MavenExecutionRequestPopulator/RootLocator
  4. Guard call sites with try/catch IllegalStateException if absence is legitimate in your tool

Example fix

// before
MavenExecutionRequest request = new DefaultMavenExecutionRequest();
Path root = request.getRootDirectory(); // IllegalStateException

// after
MavenExecutionRequest request = new DefaultMavenExecutionRequest();
request.setRootDirectory(Paths.get("/repo/root")); // or populate via RootLocator
Path root = request.getRootDirectory();
Defensive patterns

Strategy: try-catch

Validate before calling

// Locate the root the same way Maven does, before touching getRootDirectory()
Path dir = Paths.get(request.getBaseDirectory());
Path root = dir;
while (root != null && !Files.exists(root.resolve(".mvn"))) {
    root = root.getParent();
}
if (root != null) {
    request.setRootDirectory(root);
}

Try / catch

try {
    Path root = request.getRootDirectory();
} catch (IllegalStateException e) {
    // no .mvn and no root="true" pom above the cwd
    throw new IllegalStateException("Add a .mvn directory at the repo root or set root=\"true\" on the root pom", e);
}

Prevention

When it happens

Trigger: Calling getRootDirectory() on a request where setRootDirectory(...) was never invoked and directory scanning found no .mvn directory and no root="true" pom. Typical when embedding Maven (embedder, maven-invoker, tests) and constructing DefaultMavenExecutionRequest by hand instead of via the CLI locator.

Common situations: Embedders/tests building requests directly; projects that deleted the .mvn directory; tools assuming every pom hierarchy has a discoverable root; running Maven from inside an unmarked directory tree.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/dbef1629217429bb. Report an issue: GitHub.