{"record":{"id":"fb7efe38d1b21abf","repo":"HMCL-dev/HMCL","slug":"no-character-is-selected","errorCode":null,"errorMessage":"No character is selected","messagePattern":"No character is selected","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilSession.java","lineNumber":104,"sourceCode":"        Objects.requireNonNull(privateData);\n\n        String profileIDText = JsonUtils.getString(metadata, \"profileID\");\n        if (profileIDText == null) {\n            throw new IllegalArgumentException(\"profileID is missing\");\n        }\n        UUID profileID = UUIDs.parse(profileIDText);\n        String profileName = JsonUtils.getString(privateData, \"profileName\", \"\");\n        String clientToken = requireStorageString(privateData, \"clientToken\");\n        String accessToken = requireStorageString(privateData, \"accessToken\");\n        @Nullable Map<String, String> userProperties = privateData.get(\"userProperties\") instanceof JsonObject userPropertiesObject\n                ? GSON_PROPERTIES.fromJson(userPropertiesObject, JsonUtils.mapTypeOf(String.class, String.class))\n                : null;\n        return new YggdrasilSession(clientToken, accessToken, new GameProfile(profileID, profileName), null, userProperties);\n    }\n\n    public void writePrivateData(JsonObject privateData) {\n        if (selectedProfile == null)\n            throw new IllegalStateException(\"No character is selected\");\n\n        privateData.addProperty(\"clientToken\", clientToken);\n        privateData.addProperty(\"accessToken\", accessToken);\n        privateData.addProperty(\"profileName\", selectedProfile.getName());\n        privateData.add(\"userProperties\", GSON_PROPERTIES.toJsonTree(userProperties));\n    }\n\n    private static String requireStorageString(JsonObject storage, String name) {\n        String value = JsonUtils.getString(storage, name);\n        if (value == null) {\n            throw new IllegalArgumentException(name + \" is missing\");\n        }\n        return value;\n    }\n\n    public AuthInfo toAuthInfo() {\n        if (selectedProfile == null)\n            throw new IllegalStateException(\"No character is selected\");","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilSession.java#L86-L122","documentation":"Thrown by YggdrasilSession.writePrivateData when the session has no selected profile (character). Persistence requires a selected profile because profileName is written into private storage; writing without one would silently drop character info.","triggerScenarios":"Calling writePrivateData on a session created/refreshed before a character was chosen, e.g. after refresh() when selectedProfile is still null or the account owns multiple profiles and none was picked.","commonSituations":"Saving state for accounts with multiple Minecraft profiles without calling selectProfile, or persisting a freshly-created Microsoft-auth session before character selection completes.","solutions":["Select a character first (set the selected profile) before calling writePrivateData","Check selectedProfile != null and skip/persist as partial state instead of throwing","Re-authenticate to obtain a session with a selected profile"],"exampleFix":"// before\nsession.writePrivateData(privateData); // throws if no character\n// after\nif (session.getSelectedProfile() != null) {\n    session.writePrivateData(privateData);\n} else {\n    promptCharacterSelectionThenSave();\n}","handlingStrategy":"type-guard","validationCode":"if (session.getSelectedProfile() == null)\n    throw new IllegalStateException(\"Select a character before persisting session\");","typeGuard":"static boolean hasSelectedProfile(YggdrasilSession s) {\n    return s.getSelectedProfile() != null;\n}","tryCatchPattern":"try {\n    session.writePrivateData(privateData);\n} catch (IllegalStateException e) {\n    ui.promptCharacterSelection(session); // then retry save\n}","preventionTips":["Always run character selection before saving/launching flows","Check selectedProfile after every refresh() call","Persist partial state explicitly rather than assuming a profile exists"],"tags":["java","minecraft","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}