HMCL-dev/HMCL · error · FileNotFoundException

Minecraft client JAR not found

Error message

Minecraft client JAR not found: ${minecraftJar}

What it means

Thrown at the start of NeoForgeOldInstallTask.execute() when the Minecraft client JAR (minecraftJar path) is not a regular file. The installer needs the actual client jar to patch, so installation aborts immediately.

Solutions

  1. Ensure the vanilla Minecraft client JAR is downloaded/validated before running the NeoForge installer.
  2. Check the path stored in minecraftJar exists: Files.isRegularFile(path).
  3. Re-add or repair the game version so the client jar is restored.

Example fix

// before
NeoForgeOldInstallTask task = new NeoForgeOldInstallTask(dep, manifest, jar, profile);
task.execute(); // throws if jar missing
// after
if (!Files.isRegularFile(clientJar)) {
    await(new GameDownloadTask(...)); // ensure client jar first
}
task.execute();
Defensive patterns

Strategy: validation

Validate before calling

if (!Files.isRegularFile(minecraftJar))
    throw new IllegalStateException("Client JAR missing, download vanilla client first: " + minecraftJar);

Try / catch

try {
    await(task);
} catch (FileNotFoundException e) {
    // ensure vanilla client download task completes first, then retry
    await(new GameDownloadTask(dependencyManager, manifest, 'client', gameVersion));
    await(task);
}

Prevention

When it happens

Trigger: Calling execute() after the minecraftJar Path was never downloaded, points to a deleted temp file, or points to a directory/symlink that does not resolve to a regular file.

Common situations: User cancelled the vanilla client download, version isolation removed the jar, wrong game repository path, or a prior task step failed silently leaving no client jar.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/7b4c9401a9ccdbf2. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/neoforge/NeoForgeOldInstallTask.java:383

                    mappingsTask.setCacheRepository(dependencyManager.getCacheRepository());
                    return mappingsTask;
                });
    }

    private Task<?> createProcessorTask(Processor processor, Map<String, String> vars) {
        Task<?> task = patchDownloadMojangMappingsTask(processor, vars);
        if (task == null) {
            task = new ProcessorTask(processor, vars);
        }
        task.onDone().register(
                () -> updateProgress(processorDoneCount.incrementAndGet(), processors.size()));
        return task;
    }

    @Override
    public void execute() throws Exception {
        if (!Files.isRegularFile(minecraftJar)) {
            throw new FileNotFoundException("Minecraft client JAR not found: " + minecraftJar);
        }
        tempDir = Files.createTempDirectory("neoforge_installer");
        // External processors must not receive the shared cache path.
        Path isolatedMinecraftJar = tempDir.resolve("minecraft.jar");
        FileUtils.copyFile(minecraftJar, isolatedMinecraftJar);

        Map<String, String> vars = new HashMap<>();

        try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(installer)) {
            for (Map.Entry<String, String> entry : profile.getData().entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();

                vars.put(key, parseLiteral(value,
                        Collections.emptyMap(),
                        str -> {
                            Path dest = Files.createTempFile(tempDir, null, null);
                            FileUtils.copyFile(fs.getPath(str), dest);

View on GitHub (pinned to 24702dc5a0)