{"record":{"id":"13a3612407830a02","repo":"HMCL-dev/HMCL","slug":"missing-game-manifest","errorCode":null,"errorMessage":"Missing game manifest","messagePattern":"Missing game manifest","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/Instances.java","lineNumber":179,"sourceCode":"        }, instanceId.toString(),\n            new Validator(i18n(\"install.new_game.malformed\"), HMCLGameRepository::isValidInstanceId),\n            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);","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/Instances.java#L161-L197","documentation":"Instances.installFromJson reads a GameInstanceManifest JSON file to install a Minecraft game instance. If JsonUtils.fromJsonFile returns null (empty or whitespace-only file that parses to no value), it throws IllegalArgumentException('Missing game manifest'); the method catches it, logs a warning, shows a 'malformed JSON' dialog, and aborts the install.","triggerScenarios":"Calling installFromJson(repository, path) with a file that is empty, contains only whitespace/null JSON, or cannot be deserialized into a non-null GameInstanceManifest.","commonSituations":"Selecting a zero-byte or placeholder file in the import-installer UI; a download of the manifest was interrupted leaving an empty file; pointing the installer at a non-manifest JSON file.","solutions":["Ensure the file contains a complete GameInstanceManifest JSON object (non-empty, with formatVersion etc.).","Check the file size on disk — recreate/re-download the manifest if it is 0 bytes.","Export a fresh manifest from the source instance before importing.","Pre-validate with JsonUtils.fromJsonFile yourself and show a clearer error than 'malformed json'."],"exampleFix":"// before: importing an empty file silently fails\nInstances.installFromJson(repo, Path.of(\"empty.json\"));\n// after: guard first\nString content = Files.readString(file);\nif (content.isBlank()) throw new IllegalArgumentException(\"Manifest file is empty: \" + file);\nInstances.installFromJson(repo, file);","handlingStrategy":"validation","validationCode":"// validate manifest file before calling installFromJson\nstatic void requireInstallableManifest(Path file) throws IOException {\n  if (!Files.isRegularFile(file) || Files.size(file) == 0)\n    throw new IllegalArgumentException(\"manifest file missing or empty: \" + file);\n  GameInstanceManifest m = JsonUtils.fromJsonFile(file, GameInstanceManifest.class);\n  if (m == null) throw new IllegalArgumentException(\"manifest is empty/null\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  Instances.installFromJson(repository, file);\n} catch (IllegalArgumentException e) {\n  // installFromJson shows its own dialog and returns; only reached for pre-validation failures\n  Controllers.dialog(\"Manifest file is empty or unreadable\", i18n(\"message.error\"),\n      MessageDialogPane.MessageType.ERROR);\n}","preventionTips":["Check file size > 0 before importing a manifest.","Export manifests from a working instance rather than hand-writing them.","Verify JSON parses with JsonUtils.fromJsonFile before invoking the installer.","Log the file path and content snippet on failure for diagnosis."],"tags":["java","json","hmcl","installation"],"backgroundTag":"empty-required-field","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"}