HMCL-dev/HMCL · error · IllegalArgumentException
Instance
Error message
Instance
What it means
Thrown by the MultiMCModpackInstallTask update-mode constructor when the target instance has no modpack configuration file on disk. HMCL only allows updating instances that were originally installed from a modpack and recorded as such; an instance without modpackConfiguration.json cannot be updated in place.
Solutions
- Install the modpack into a new instance instead of using the update-mode constructor.
- Verify the instance has a valid modpack configuration file before constructing the task.
- Delete the instance and reinstall the modpack from its archive.
Example fix
// before
task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, existingInstance);
// after
if (Files.exists(dm.getGameRepository().getLayout().getModpackConfigurationFile(existingInstance.getId()))) {
task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, existingInstance);
} else {
task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, new GameInstanceID("fresh-instance"));
} Defensive patterns
Strategy: validation
Validate before calling
Path cfg = dm.getGameRepository().getLayout().getModpackConfigurationFile(instance.getId());
if (Files.notExists(cfg)) { /* install fresh instead of constructing update task */ } Try / catch
try { task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, instance); } catch (IllegalArgumentException e) { task = new MultiMCModpackInstallTask(dm, zip, modpack, cfg, newId); } Prevention
- Only pass update targets that were installed via a modpack task
- Check for modpackConfiguration.json before choosing update mode
- Never delete modpack configuration files from instances
When it happens
Trigger: Constructing MultiMCModpackInstallTask with the 5-argument constructor taking a DefaultGameInstance (update mode) when repository.getLayout().getModpackConfigurationFile(instanceId) does not exist, i.e. the instance was created manually or not via a modpack install.
Common situations: User picks 'update modpack' on an instance created from scratch or imported without a modpack configuration; the configuration file was deleted; the instance belongs to a different launcher layout.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Instance
- Instance is not a Curse modpack. Cannot update this…
- Game instance already exists:
- Game instance no longer exists:
- Cannot load modpacks without Minecraft.
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/77315e20fdd44b50.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/modpack/multimc/MultiMCModpackInstallTask.java:148
Path zipFile,
Modpack modpack,
MultiMCInstanceConfiguration manifest,
GameInstanceID instanceId,
@Nullable DefaultGameInstance updateTarget) {
this.zipFile = zipFile;
this.modpack = modpack;
this.manifest = manifest;
this.instanceId = instanceId;
this.updateTarget = updateTarget;
this.dependencyManager = dependencyManager;
this.repository = dependencyManager.getGameRepository();
if (this.updateTarget != null) {
dependencyManager.validateGameInstance(this.updateTarget);
}
Path json = repository.getLayout().getModpackConfigurationFile(instanceId);
if (this.updateTarget != null && Files.notExists(json))
throw new IllegalArgumentException("Instance " + instanceId + " is not a MultiMC modpack. Cannot update this instance.");
@Nullable ModpackConfiguration<MultiMCInstanceConfiguration> config = null;
try {
if (this.updateTarget != null && Files.exists(json)) {
config = JsonUtils.fromJsonFile(json, ModpackConfiguration.typeOf(MultiMCInstanceConfiguration.class));
if (config == null || !MultiMCModpackProvider.INSTANCE.getName().equals(config.getType()))
throw new IllegalArgumentException("Instance " + instanceId + " is not a MultiMC modpack. Cannot update this instance.");
}
} catch (JsonParseException | IOException ignore) {
}
this.config = config;
onDone().register(event -> {
abortOpenDraft();
if (event.isFailed() && newInstallationReserved)
repository.removeInstanceFromDisk(instanceId);
});View on GitHub (pinned to 24702dc5a0)