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

  1. Install the missing parent version the manifest inherits from
  2. Point inheritsFrom at an existing registered instance id
  3. Remove the inheritsFrom field to make the instance standalone
  4. 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

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)