HMCL-dev/HMCL · error · FileNotFoundException

Entry not found

Error message

Entry not found: {entryPath}

What it means

ArchiveFileTree.getInputStream(String entryPath) looks up the entry by path and throws FileNotFoundException 'Entry not found: <entryPath>' when no entry with that path exists in the archive. This is the string-based overload; entry objects bypass the check.

Solutions

  1. Check the entry exists first with getEntry(entryPath) != null before opening the stream.
  2. List entries (or use the tree traversal) to find the correct exact path, including case.
  3. Handle the FileNotFoundException and treat the missing file as a soft failure (e.g. mod without plugin.yml).
  4. Verify you opened the intended archive (right jar/version).

Example fix

// before
InputStream in = tree.getInputStream("fabric.mod.json"); // FileNotFoundException if absent
// after
if (tree.getEntry("fabric.mod.json") != null) {
    InputStream in = tree.getInputStream("fabric.mod.json");
} else {
    // fallback: not a fabric mod
}
Defensive patterns

Strategy: validation

Validate before calling

if (tree.getEntry("fabric.mod.json") != null) {
    try (InputStream in = tree.getInputStream("fabric.mod.json")) { /* ... */ }
}

Try / catch

try {
    InputStream in = tree.getInputStream(entryPath);
} catch (FileNotFoundException e) {
    // entry absent; treat as missing file
}

Prevention

When it happens

Trigger: Calling getInputStream("path/in/archive") with a path that does not match any entry — missing entry, wrong casing, missing leading/trailing slash conventions, or path present only in a different archive.

Common situations: Reading well-known files like 'fabric.mod.json' or 'plugin.yml' from jars that turn out to be of the other type; files removed/renamed in newer versions of a mod.

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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/tree/ArchiveFileTree.java:175

            dir = dir.subDirs.computeIfAbsent(item, Dir::new);

            if (isLastPart) {
                if (dir.entry == null)
                    dir.entry = entry;
                else if (!dir.entry.isDirectory())
                    LOG.warning("A file and a directory have the same name: " + entry.getName());
                break;
            }
        }
    }

    public abstract InputStream getInputStream(E entry) throws IOException;

    public @NotNull InputStream getInputStream(String entryPath) throws IOException {
        E entry = getEntry(entryPath);
        if (entry == null)
            throw new FileNotFoundException("Entry not found: " + entryPath);
        return getInputStream(entry);
    }

    public BufferedReader getBufferedReader(@NotNull E entry) throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream(entry), StandardCharsets.UTF_8));
    }

    public @NotNull BufferedReader getBufferedReader(String entryPath) throws IOException {
        E entry = getEntry(entryPath);
        if (entry == null)
            throw new FileNotFoundException("Entry not found: " + entryPath);
        return getBufferedReader(entry);
    }

    public byte[] readBinaryEntry(@NotNull E entry) throws IOException {
        try (InputStream input = getInputStream(entry)) {
            return input.readAllBytes();
        }

View on GitHub (pinned to 24702dc5a0)