HMCL-dev/HMCL · error · JsonParseException
Manifest is null
Error message
Manifest is null
What it means
readInstanceManifest() loads an instance manifest JSON from disk into GameInstanceManifest; JsonUtils.fromJsonFile may legitimately return null (e.g. file parsed as an empty document), which would silently produce a broken instance. HMCL deliberately throws JsonParseException('Manifest is null') so a null manifest aborts instance loading instead of being passed downstream. Called from loadInstanceDirectory when scanning the instances directory.
Solutions
- Delete or restore the empty/null manifest file and let the repository re-import or recreate the instance
- Re-download or re-copy the complete instance directory including a valid manifest json
- Wrap instance loading in try-catch for JsonParseException and skip/report that instance instead of failing the whole repository scan
- Check for 0-byte files under the instance directory before loading
Example fix
// before
GameInstanceManifest m = repo.loadInstance(dir); // throws on empty manifest
// after
try {
GameInstanceManifest m = repo.loadInstance(dir);
} catch (JsonParseException e) {
LOG.warning("Skipping broken instance at " + dir + ": " + e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
Path manifest = dir.resolve("instance.json");
boolean valid = Files.isRegularFile(manifest) && Files.size(manifest) > 2;
if (!valid) restoreOrRecreateManifest(dir); Try / catch
try {
GameInstanceManifest m = repo.loadInstanceDirectory(dir);
} catch (JsonParseException e) {
LOG.warning("Skipping instance with null/corrupt manifest: " + dir);
} Prevention
- Write manifests atomically (temp file + atomic move)
- Check for empty files after sync/copy operations
- Back up instance metadata before migrating instances
When it happens
Trigger: Calling loadInstanceDirectory / opening a repository on a manifest json that parses to null — typically an empty file (0 bytes) or a file containing only 'null' — inside versions/<id>/instance.json-style manifests.
Common situations: Interrupted instance creation or migration leaving an empty manifest file; a crash during write; users copying instance folders but truncating files; sync tools uploading empty placeholders.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- json.toString()
- json.toString()
- e
- Account private data is not an object
- authlib-injectors.json -> urls cannot be null.
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/7794a5051e3ec54a.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java:367
try {
manifest = readInstanceManifest(json);
} catch (Exception e) {
LOG.warning("Malformed instance json " + id + " (" + json + ")", e);
return null;
}
// Directory name is the repository identity; keep the on-disk files untouched.
if (!id.equals(manifest.id())) {
manifest = manifest.withId(id);
}
return createInstance(snapshot, id, manifest, manifestFileOverride);
}
private static GameInstanceManifest readInstanceManifest(Path json) throws IOException, JsonParseException {
GameInstanceManifest manifest = JsonUtils.fromJsonFile(json, GameInstanceManifest.class);
if (manifest == null) {
throw new JsonParseException("Manifest is null");
}
return manifest;
}
static void moveInstanceFiles(Path baseDirectory, GameInstanceID from, GameInstanceID to) throws IOException {
Path instancesDir = baseDirectory.resolve("versions");
Path fromDir = instancesDir.resolve(from.id());
Path toDir = instancesDir.resolve(to.id());
Files.move(fromDir, toDir);
Path fromJson = toDir.resolve(from + ".json");
Path fromJar = toDir.resolve(from + ".jar");
Path toJson = toDir.resolve(to + ".json");
Path toJar = toDir.resolve(to + ".jar");
boolean hasJarFile = Files.exists(fromJar);
try {View on GitHub (pinned to 24702dc5a0)