HMCL-dev/HMCL · error · NoSuchGameInstanceException

${from}

Error message

${from}

What it means

Draft.rename(from, to) renames an existing instance to a new id. It throws NoSuchGameInstanceException (message = the source id 'from') when the source instance does not exist in the draft's manifest map, and IllegalStateException if 'from' was created by this same draft (renaming such instances is not allowed).

Solutions

  1. Ensure the source instance exists in the base repository (not just in the draft) before renaming
  2. Commit the draft first, then reopen a new draft to perform the rename if the instance was created in the same draft
  3. Catch NoSuchGameInstanceException and refresh the instance list in the UI
  4. Validate the from id against the snapshot's instance list before issuing rename

Example fix

// before
Draft d = repo.openDraft();
GameInstanceID id = d.put(manifest);
d.rename(id, newId); // IllegalStateException
// after
d.commit();
try (Draft d2 = repo.openDraft()) {
    d2.rename(id, newId);
}
Defensive patterns

Strategy: type-guard

Validate before calling

boolean canRename = repository.getInstanceIds().contains(from)
        && !repository.getInstanceIds().contains(to);

Type guard

boolean renameable = !createdIds.contains(from) && manifests.containsKey(from);

Try / catch

try {
    draft.rename(from, to);
} catch (NoSuchGameInstanceException | IllegalStateException e) {
    LOG.warning("Cannot rename " + from + ": " + e.getMessage());
}

Prevention

When it happens

Trigger: Renaming an instance that does not exist (typo, removed elsewhere, or created by this draft rather than pre-existing); renaming an id that is still pending creation in createdIds.

Common situations: User renames an instance concurrently deleted in another window; automation renaming freshly created instances without committing first; stale ids from a previous repository snapshot.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/56a3ae80ca9973bc. Report an issue: GitHub.

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepositoryDraft.java:164

    @Override
    public void remove(GameInstanceID instanceId) {
        checkOpen();
        if (manifests.remove(instanceId) == null) {
            throw new NoSuchGameInstanceException(instanceId);
        }

        modifiedIds.remove(instanceId);
        primaryJarSources.remove(instanceId);
        removedIds.add(instanceId);
    }

    /// {@inheritDoc}
    @Override
    public void rename(GameInstanceID from, GameInstanceID to) throws IOException {
        checkOpen();
        @Nullable GameInstanceManifest source = manifests.get(from);
        if (source == null) {
            throw new NoSuchGameInstanceException(from);
        }
        if (createdIds.contains(from)) {
            throw new IllegalStateException("Cannot rename an instance created by the same draft");
        }
        if (manifests.containsKey(to)) {
            throw new IllegalArgumentException("Target instance already exists: " + to);
        }

        Path targetRoot = baseSnapshot.getLayout().getInstanceRoot(to);
        if (Files.exists(targetRoot)) {
            throw new FileAlreadyExistsException(targetRoot.toString());
        }

        GameInstanceManifest renamedManifest = source;
        if (from.equals(renamedManifest.jar())) {
            renamedManifest = renamedManifest.withJar(null);
        }
        renamedManifest = renamedManifest.withId(to);

View on GitHub (pinned to 24702dc5a0)