quarkusio/quarkus · error · java.lang.RuntimeException

rootPath is null for

Error message

rootPath is null for 

What it means

OpenContainerPathTree.getRoots() resolves the container's root path; if the underlying archive/directory could not be opened (the open container has no root), it throws a plain RuntimeException. This signals that the tree was constructed for a path that failed to open, so the root does not exist.

Source

Thrown at independent-projects/bootstrap/app-model/src/main/java/io/quarkus/paths/OpenContainerPathTree.java:65

     * This is the path to the container.
     * <p>
     * In the case of a zip archive, it's the path to the root of the archive (i.e. a ZipPath).
     * In the case of a directory, it's the directory.
     * <p>
     * Should be used for any read operation on the container.
     */
    protected abstract Path getRootPath();

    @Override
    public OpenPathTree open() {
        return this;
    }

    @Override
    public Collection<Path> getRoots() {
        final Path rootPath = getRootPath();
        if (rootPath == null) {
            throw new RuntimeException("rootPath is null for " + getContainerPath());
        }
        return List.of(rootPath);
    }

    @Override
    public void walk(PathVisitor visitor) {
        final Path rootPath = getRootPath();
        if (!Files.exists(rootPath)) {
            return;
        }
        PathTreeVisit.walk(getContainerPath(), rootPath, rootPath, pathFilter, getMultiReleaseMapping(),
                visitor);

    }

    @Override
    public void walkRaw(PathVisitor visitor) {
        final Path rootPath = getRootPath();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the container path (printed in the message) exists before creating/using the tree: Files.exists(containerPath).
  2. Re-create the PathTree from a fresh Path if the archive was rebuilt or moved.
  3. If you cache trees, invalidate the cache when the underlying file's timestamp/size changes.
  4. Guard usage with isOpen()/getRootPath() null-check when available instead of catching the RuntimeException.

Example fix

// before
OpenContainerPathTree tree = OpenContainerPathTree.forPath(jarPath);
Path root = tree.getRoots().iterator().next(); // RuntimeException if not open
// after
OpenContainerPathTree tree = OpenContainerPathTree.forPath(jarPath);
if (tree.getRootPath() == null) {
    throw new IllegalStateException("Archive failed to open: " + jarPath);
}
Path root = tree.getRoots().iterator().next();
Defensive patterns

Strategy: validation

Validate before calling

if (!Files.isRegularFile(containerPath)) {
    throw new IllegalStateException("Container missing: " + containerPath);
}
OpenContainerPathTree tree = OpenContainerPathTree.forPath(containerPath);
if (tree.getRootPath() == null) {
    throw new IllegalStateException("Failed to open: " + containerPath);
}

Type guard

static boolean hasRoot(OpenContainerPathTree tree) {
    return tree != null && tree.getRootPath() != null;
}

Try / catch

try {
    Collection<Path> roots = tree.getRoots();
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("rootPath is null")) {
        // re-create tree from a fresh Path
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling getRoots() (or walk/apply consumers that use it) on an OpenContainerPathTree whose getRootPath() returned null — typically because the archive file disappeared or failed to open when the tree was created.

Common situations: A dependency JAR was deleted from the local Maven repo or a fat-jar/lib directory while the application was running; caching an OpenContainerPathTree across builds where the underlying archive was cleaned.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/3ec6e5d2f69d7dc1. Report an issue: GitHub.