{"record":{"id":"0a9e70e596e68d4b","repo":"HMCL-dev/HMCL","slug":"invalid-game-instance-id","errorCode":null,"errorMessage":"Invalid game instance id: ","messagePattern":"Invalid game instance id: ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameInstanceID.java","lineNumber":59,"sourceCode":"\n    /// Returns whether `id` is a non-blank instance path segment.\n    ///\n    /// @param id the candidate id\n    /// @return whether the id satisfies the repository-independent safety requirements\n    public static boolean isValid(String id) {\n        return !id.isBlank()\n                && !id.equals(\".\")\n                && !id.equals(\"..\")\n                && !id.contains(\"/\")\n                && !id.contains(\"\\\\\");\n    }\n\n    /// Creates a validated instance id.\n    ///\n    /// @throws IllegalArgumentException if `id` is not valid\n    public GameInstanceID {\n        if (!isValid(id)) {\n            throw new IllegalArgumentException(\"Invalid game instance id: \" + id);\n        }\n    }\n\n    /// {@inheritDoc}\n    @Override\n    public int compareTo(GameInstanceID that) {\n        return this.id.compareTo(that.id);\n    }\n\n    /// Returns the instance id string.\n    ///\n    /// @return the value supplied to the constructor\n    @Override\n    public String toString() {\n        return id;\n    }\n\n    /// Serializes nullable instance ids as JSON strings.","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/game/GameInstanceID.java#L41-L77","documentation":"GameInstanceID's compact constructor validates the id string with isValid(id) and throws IllegalArgumentException when it is not a valid instance id. The library enforces identifier rules (e.g. no illegal characters) so ids are safe to map to directory names. The message includes the offending id value (here shown with an empty/absent id).","triggerScenarios":"new GameInstanceID(\"\") or null/blank string; constructing ids from raw user input or parsed JSON without validation; ids containing path separators or reserved characters rejected by isValid.","commonSituations":"Empty 'id' field in a version/instance JSON; user submitted an empty name; code passing an untrimmed string of whitespace; deserialization feeding arbitrary strings into the constructor.","solutions":["Validate the string with GameInstanceID.isValid(id) before constructing","Trim/require a non-empty id from user input or JSON before parsing","Sanitize or reject ids with illegal characters per isValid's rules","Fix the source JSON so the id field is present and well-formed"],"exampleFix":"// before\nGameInstanceID id = new GameInstanceID(json.get(\"id\").getAsString()); // may be \"\"\n// after\nString raw = json.get(\"id\").getAsString().trim();\nif (!GameInstanceID.isValid(raw)) throw new JsonParseException(\"bad id\");\nGameInstanceID id = new GameInstanceID(raw);","handlingStrategy":"validation","validationCode":"String raw = input == null ? \"\" : input.trim();\nif (!GameInstanceID.isValid(raw)) throw new IllegalArgumentException(\"Invalid instance id: \" + raw);\nGameInstanceID id = new GameInstanceID(raw);","typeGuard":"static boolean isSafeId(String s) {\n    return s != null && !s.isBlank() && GameInstanceID.isValid(s.trim());\n}","tryCatchPattern":"try { id = new GameInstanceID(raw); }\ncatch (IllegalArgumentException e) { id = null; LOG.warning(e.getMessage()); }","preventionTips":["Always validate with GameInstanceID.isValid before constructing","Trim and require non-empty user-provided names","Sanitize ids parsed from JSON before wrapping them in GameInstanceID"],"tags":["validation","identifier","illegal-argument"],"backgroundTag":"invalid-identifier-format","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"}