HMCL-dev/HMCL · error · IllegalStateException

Game instance already exists:

Error message

Game instance already exists: 

What it means

preExecute reserves the target instance inside a repository draft; in install mode (updateTarget == null) the instance must not already exist. Thrown when the base snapshot reports the instance ID as present, preventing an accidental overwrite of an existing instance.

Solutions

  1. Choose a different instanceId for the new installation.
  2. Delete or rename the existing instance first.
  3. Use the update-mode constructor with the existing DefaultGameInstance to update in place.

Example fix

// before
task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, existingId);
// after
if (!repository.hasInstance(existingId)) {
    task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, existingId);
} else {
    task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, repository.getInstance(existingId)); // update
}
Defensive patterns

Strategy: validation

Validate before calling

if (repository.hasInstance(instanceId)) { /* use update mode or pick another id */ }

Try / catch

try { task.run(); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Game instance already exists")) { /* rename or delete */ } }

Prevention

When it happens

Trigger: Running a new-installation MultiMCModpackInstallTask (no DefaultGameInstance update target) whose instanceId already exists in the repository at execution time.

Common situations: Installing the same modpack twice under the same instance name; a race where another task created the instance between task construction and execution.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackInstallTask.java:183

                repository.removeInstanceFromDisk(instanceId);
        });
    }

    @Override
    public boolean doPreExecute() {
        return true;
    }

    /// Reserves the instance in a repository draft before preparing tasks that write its root.
    @Override
    public void preExecute() throws Exception {
        DefaultGameRepositoryDraft openedDraft = repository.openDraft();
        draft = openedDraft;
        try {
            // Construction fixes the mode; the captured snapshot only verifies that it is still valid.
            boolean targetExists = openedDraft.getBaseSnapshot().hasInstance(instanceId);
            if (this.updateTarget == null && targetExists) {
                throw new IllegalStateException("Game instance already exists: " + instanceId);
            }
            if (this.updateTarget != null && !targetExists) {
                throw new IllegalStateException("Game instance no longer exists: " + instanceId);
            }

            openedDraft.put(new GameInstanceManifest(instanceId));
            newInstallationReserved = this.updateTarget == null;
        } catch (IOException | RuntimeException e) {
            try {
                openedDraft.abort();
            } catch (IOException cleanupFailure) {
                e.addSuppressed(cleanupFailure);
            }
            draft = null;
            throw e;
        }

        // Stage #0: General Setup

View on GitHub (pinned to 24702dc5a0)