quarkusio/quarkus · error · UncheckedIOException

Error while searching for recipe directories in ${startDir}

Error message

Error while searching for recipe directories in ${startDir}

What it means

findDirsWithRecipes() walks a start directory with a stream of paths and collects parent directories of matching recipe files; if the walk itself throws IOException it throws UncheckedIOException("Error while searching for recipe directories in <startDir>"). This is the outermost guard for directory-tree traversal failures, called by findRecipeDirectories.

Source

Thrown at independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdatesRepository.java:245

            Map<String, VersionUpdate> recipeDirectoryNames) {
        return findDirsWithRecipes(rootDir).stream()
                .map(d -> {
                    String relativeDir = rootDir.relativize(d).toString();
                    return resolveVersionsForRecipesDir(relativeDir, toKey(relativeDir), recipeDirectoryNames);
                })
                .filter(Optional::isPresent)
                .map(Optional::get);
    }

    public static Set<Path> findDirsWithRecipes(Path startDir) {
        try (var stream = Files.walk(startDir)) {
            return stream
                    .filter(Files::isRegularFile)
                    .filter(QuarkusUpdatesRepository::isRecipeFile)
                    .map(Path::getParent)
                    .collect(Collectors.toSet()); // Ensures no duplicates
        } catch (IOException e) {
            throw new UncheckedIOException("Error while searching for recipe directories in " + startDir, e);
        }
    }

    private static String toKey(ExtensionUpdateInfo dep) {
        return String.format("%s:%s", dep.getCurrentDep().getArtifact().getGroupId(),
                dep.getCurrentDep().getArtifact().getArtifactId());
    }

    static String toKey(String relativeDir) {
        return relativeDir
                .replaceAll("(^[/\\\\])|([/\\\\]$)", "")
                .replaceAll("[/\\\\]", ":");
    }

    static Optional<RecipeDirectory> resolveVersionsForRecipesDir(String dir, String key,
            Map<String, VersionUpdate> recipeDirectoryNames) {
        final Set<VersionUpdate> matches = recipeDirectoryNames.entrySet().stream()
                .filter(e -> e.getKey().startsWith(key))

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the start directory exists and is readable (ls the path shown in the message).
  2. Re-create the recipes cache by re-running the update or reinstalling the update artifact.
  3. Fix permissions on the directory tree (chmod -R u+rX).
  4. Remove broken symlinks or unreadable subdirectories inside the tree and retry.

Example fix

// shell: inspect and restore the recipes root
ls ~/.quarkus/update-recipes || mkdir -p ~/.quarkus/update-recipes
chmod -R u+rwX ~/.quarkus/update-recipes
Defensive patterns

Strategy: try-catch

Validate before calling

if (!Files.isDirectory(startDir) || !Files.isReadable(startDir)) {
    throw new IOException("Recipes start directory missing or unreadable: " + startDir);
}

Try / catch

try {
    Set<Path> dirs = QuarkusUpdatesRepository.findDirsWithRecipes(startDir);
} catch (UncheckedIOException e) {
    log.error("Cannot search recipes in " + startDir + ": " + e.getCause(), e);
}

Prevention

When it happens

Trigger: findDirsWithRecipes (called by findRecipeDirectories during `quarkus update`) invokes Files.walk (or similar) on startDir and the traversal throws IOException — startDir does not exist, is not readable, or traversal hits an unreadable subtree.

Common situations: Running `quarkus update` where the local recipes cache directory was never created or was deleted; permissions on the cache root; a broken symlink cycle or unreadable directory inside the tree; read-only/failed mount.

Related errors


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