HMCL-dev/HMCL · error · FileNotFoundException

Game processor file not found, should be downloaded in…

Error message

Game processor file not found, should be downloaded in preprocess

What it means

ProcessorTask.execute() throws FileNotFoundException when the processor's jar artifact is not a regular file in the game repository. Processor JARs are expected to have been downloaded in the preprocess (dependency/libraries download) stage; their absence means the required libraries were never fetched or were deleted. The processor cannot be launched without this JAR.

Solutions

  1. Re-run the Forge installation so the dependent GameLibrariesTask downloads the processor libraries first
  2. Check that the libraries directory contains the processor jar (e.g. libraries/net/minecraftforge/installertools/...)
  3. Verify the game repository base directory points at the same location used during preprocessing
  4. Fix network/proxy issues and retry the full download task rather than only running processors

Example fix

// before: running processors without downloading libraries
task.run();
// after: ensure dependencies (library downloads) complete first
Task<?> install = new ForgeNewInstallTask(dependencyManager, manifest, minecraftJar, version, installer);
install.whenComplete(...); // dependencies include GameLibrariesTask + processorsTask
Defensive patterns

Strategy: validation

Validate before calling

// Confirm processor jars exist before running the task
Path jar = gameRepository.getLayout().getArtifactFile(processor.getJar());
if (!Files.isRegularFile(jar)) {
    throw new IOException("Preprocess missing processor jar: " + jar + "; re-run library downloads");
}

Try / catch

try {
    installTask.run();
} catch (FileNotFoundException e) {
    if (e.getMessage().contains("preprocess")) {
        // re-run dependency downloads (GameLibrariesTask) then retry
    }
}

Prevention

When it happens

Trigger: Running a Forge processor after the libraries download stage skipped, failed silently, or stored files in a different repository location; calling ProcessorTask directly without GameLibrariesTask having completed; the repository path layout resolving processor.getJar() to a nonexistent file.

Common situations: Offline installation with missing libraries; a game directory with partially deleted 'libraries' folder; network failure during the dependent download task that was ignored; mismatched game repository (BASE directory) between sessions.

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/30254b20b9d26865. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/download/forge/ForgeNewInstallTask.java:114

                    if (!Objects.equals(code, value)) {
                        Files.delete(artifact);
                        LOG.info("Found existing file is not valid: " + artifact);

                        miss = true;
                    }
                } else {
                    miss = true;
                }
            }

            if (!processor.getOutputs().isEmpty() && !miss) {
                return;
            }

            Path jar = gameRepository.getLayout().getArtifactFile(processor.getJar());
            if (!Files.isRegularFile(jar))
                throw new FileNotFoundException("Game processor file not found, should be downloaded in preprocess");

            String mainClass;
            try (JarFile jarFile = new JarFile(jar.toFile())) {
                mainClass = jarFile.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
            }

            if (StringUtils.isBlank(mainClass))
                throw new Exception("Game processor jar does not have main class " + jar);

            List<String> command = new ArrayList<>();
            command.add(JavaRuntime.getDefault().getBinary().toString());
            command.add("-cp");

            List<String> classpath = new ArrayList<>(processor.getClasspath().size() + 1);
            for (Artifact artifact : processor.getClasspath()) {
                Path file = gameRepository.getLayout().getArtifactFile(artifact);
                if (!Files.isRegularFile(file))
                    throw new Exception("Game processor dependency missing");

View on GitHub (pinned to 24702dc5a0)