{"record":{"id":"b2bc62e5e4b1f35e","repo":"HMCL-dev/HMCL","slug":"game-manifest-inherits-from-another-manifest","errorCode":null,"errorMessage":"Game manifest inherits from another manifest","messagePattern":"Game manifest inherits from another manifest","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/Instances.java","lineNumber":181,"sourceCode":"            new Validator(i18n(\"install.new_game.already_exists\"), newVersionName -> !repository.instanceIdConflicts(newVersionName) || newVersionName.equals(instanceId.toString())));\n    }\n\n    public static void exportInstance(HMCLGameInstance gameInstance) {\n        Controllers.getDecorator().startWizard(new ExportWizardProvider(gameInstance), i18n(\"modpack.wizard\"));\n    }\n\n    public static void openFolder(HMCLGameInstance gameInstance) {\n        FXUtils.openFolder(gameInstance.getRunDirectory());\n    }\n\n    public static void installFromJson(HMCLGameRepository repository, Path file) {\n        GameInstanceManifest manifest;\n        try {\n            manifest = JsonUtils.fromJsonFile(file, GameInstanceManifest.class);\n            if (manifest == null)\n                throw new IllegalArgumentException(\"Missing game manifest\");\n            if (manifest.inheritsFrom() != null)\n                throw new IllegalArgumentException(\"Game manifest inherits from another manifest\");\n        } catch (Exception e) {\n            LOG.warning(\"Failed to read game manifest from \" + file, e);\n            Controllers.dialog(i18n(\"install.new_game.malformed_json\"), i18n(\"message.error\"), MessageDialogPane.MessageType.ERROR);\n            return;\n        }\n\n        Controllers.prompt(i18n(\"instance.manage.duplicate.prompt\"), (result, handler) -> {\n            handler.resolve();\n\n            GameInstanceID instanceId = new GameInstanceID(result);\n\n            DefaultDependencyManager dependencyManager = repository.getDependency();\n            GameInstanceManifest newManifest = manifest.withId(instanceId).withJar(instanceId);\n            GameDownloadTask gameDownloadTask = new GameDownloadTask(\n                    dependencyManager,\n                    newManifest);\n            AtomicReference<GameRepositoryDraft> activeDraft = new AtomicReference<>();\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/Instances.java#L163-L199","documentation":"GameInstanceManifest supports inheritance via an inheritsFrom field; installFromJson refuses manifests that declare inheritance because the installer cannot resolve the parent manifest. It throws IllegalArgumentException('Game manifest inherits from another manifest'), which installFromJson catches, logs, shows a 'malformed JSON' dialog, and returns without installing.","triggerScenarios":"Importing a manifest JSON whose inheritsFrom property is non-null — typically an exported/subset manifest that references a parent instance, fed to Instances.installFromJson.","commonSituations":"Hand-editing an exported manifest and leaving inheritsFrom in place; exporting only part of an instance chain; using manifests generated for a different installer that supports inheritance.","solutions":["Remove the inheritsFrom field and inline/merge any parent manifest fields before importing.","Export the full self-contained instance manifest instead of a child manifest.","If the parent exists, import the parent manifest first or use the full-instance export flow.","Strip the field programmatically before calling installFromJson if inheritance is not needed."],"exampleFix":"// before: child manifest rejected\nInstances.installFromJson(repo, Path.of(\"child-manifest.json\")); // inheritsFrom != null\n// after: inline the parent, then import\nGameInstanceManifest m = JsonUtils.fromJsonFile(file, GameInstanceManifest.class);\nGameInstanceManifest merged = mergeWithParent(m);\nFiles.write(file, JsonUtils.toJson(merged).getBytes());\nInstances.installFromJson(repo, file);","handlingStrategy":"validation","validationCode":"// reject or resolve inheritance before install\nGameInstanceManifest m = JsonUtils.fromJsonFile(file, GameInstanceManifest.class);\nif (m != null && m.inheritsFrom() != null) {\n  Path parent = resolveParentManifest(m.inheritsFrom());\n  if (parent == null)\n    throw new IllegalArgumentException(\"inheritsFrom '\" + m.inheritsFrom() + \"' cannot be resolved; export a self-contained manifest\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  Instances.installFromJson(repository, file);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"inherits\")) {\n    Controllers.dialog(\"This manifest inherits from another instance; import a full manifest instead\",\n        i18n(\"message.error\"), MessageDialogPane.MessageType.ERROR);\n  }\n}","preventionTips":["Always export self-contained manifests (no inheritsFrom) when moving instances between setups.","If using inheritance, ship the parent manifest too and import in dependency order.","Strip or inline inheritsFrom programmatically before importing child manifests.","Read the manifest JSON in an editor to confirm no inheritance remains before importing."],"tags":["java","json","hmcl","installation"],"backgroundTag":"schema-validation-failed","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}