HMCL-dev/HMCL · error · NoSuchGameInstanceException
${inheritsFrom}
Error message
${inheritsFrom} What it means
DefaultGameRepositorySnapshot.resolve walks the inheritsFrom chain of a manifest and throws NoSuchGameInstanceException when a manifest declares a parent instance id that is not registered in the snapshot. The message is the missing parent id. Circular dependencies are handled separately by breaking the chain, but a dangling parent is a hard error.
Solutions
- Install the missing parent version the manifest inherits from
- Point inheritsFrom at an existing registered instance id
- Remove the inheritsFrom field to make the instance standalone
- Re-scan the repository if the parent exists on disk but is unregistered
Example fix
// before "inheritsFrom": "1.20.1-forge" // not installed // after "inheritsFrom": "1.20.1" // installed parent, or omit to be standalone
Defensive patterns
Strategy: try-catch
Validate before calling
GameInstanceID parent = manifest.inheritsFrom();
if (parent != null && !snapshot.hasInstance(parent)) { /* install parent or clear inheritsFrom */ } Type guard
static boolean inheritanceChainResolvable(DefaultGameRepositorySnapshot s, GameInstanceManifest m) {
GameInstanceID p = m.inheritsFrom();
return p == null || s.hasInstance(p);
} Try / catch
try { instance = snapshot.getInstance(childId); }
catch (NoSuchGameInstanceException e) { installParent(e.getMessage()); instance = snapshot.getInstance(childId); } Prevention
- Never delete a parent version while children inherit from it
- Validate inheritsFrom against registered ids at manifest load time
- Break inheritance (set null) for standalone copies of version JSON
When it happens
Trigger: Resolving (getInstance on a child instance) whose manifest.inheritsFrom names an unregistered/missing id — e.g. child installed while the parent version was never installed or was deleted.
Common situations: Deleting a base version (e.g. a vanilla version) that modded children inherit from; copying a version JSON to another launcher without its parent; version JSON edited to point at a nonexistent parent id.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/8f3d546a21f5cdfd.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepositorySnapshot.java:258
: manifest;
} else {
resolvedManifest = manifest;
}
resolvedManifest = resolvedManifest.withJar(manifest.jar() == null ? manifest.id() : manifest.jar());
} else {
if (resolvedSoFar == null) {
resolvedSoFar = new HashSet<>();
}
// To maximize the compatibility.
if (!resolvedSoFar.add(manifest.id())) {
LOG.warning("Found circular dependency instances: " + resolvedSoFar);
resolvedManifest = (manifest.jar() == null ? manifest.withJar(manifest.id()) : manifest)
.withInheritsFrom(null);
} else {
DefaultGameInstance parentInstance = instances.get(manifest.inheritsFrom());
if (parentInstance == null) {
throw new NoSuchGameInstanceException(manifest.inheritsFrom());
}
// It is supposed to auto-install a version in getVersion.
GameInstanceManifest parentResolved = resolve(parentInstance.getManifest(), resolvedSoFar);
resolvedManifest = manifest.merge(parentResolved);
}
}
var builder = new GameInstanceManifest.Builder(resolvedManifest);
if (manifest.patches() != null && !manifest.patches().isEmpty()) {
// Assume patches themselves do not have patches recursively.
List<GameInstancePatch> sortedPatches = manifest.patches().stream()
.sorted(Comparator.comparing(GameInstancePatch::getPriority))
.toList();
for (GameInstancePatch patch : sortedPatches) {
builder.merge(patch);
}View on GitHub (pinned to 24702dc5a0)