HMCL-dev/HMCL · error · IllegalStateException
No character is selected
Error message
No character is selected
What it means
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.
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
Example fix
// before
session.writePrivateData(privateData); // throws if no character
// after
if (session.getSelectedProfile() != null) {
session.writePrivateData(privateData);
} else {
promptCharacterSelectionThenSave();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (session.getSelectedProfile() == null)
throw new IllegalStateException("Select a character before persisting session"); Type guard
static boolean hasSelectedProfile(YggdrasilSession s) {
return s.getSelectedProfile() != null;
} Try / catch
try {
session.writePrivateData(privateData);
} catch (IllegalStateException e) {
ui.promptCharacterSelection(session); // then retry save
} Prevention
- Always run character selection before saving/launching flows
- Check selectedProfile after every refresh() call
- Persist partial state explicitly rather than assuming a profile exists
When it happens
Trigger: 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.
Common situations: Saving state for accounts with multiple Minecraft profiles without calling selectProfile, or persisting a freshly-created Microsoft-auth session before character selection completes.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/fb7efe38d1b21abf.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilSession.java:104
Objects.requireNonNull(privateData);
String profileIDText = JsonUtils.getString(metadata, "profileID");
if (profileIDText == null) {
throw new IllegalArgumentException("profileID is missing");
}
UUID profileID = UUIDs.parse(profileIDText);
String profileName = JsonUtils.getString(privateData, "profileName", "");
String clientToken = requireStorageString(privateData, "clientToken");
String accessToken = requireStorageString(privateData, "accessToken");
@Nullable Map<String, String> userProperties = privateData.get("userProperties") instanceof JsonObject userPropertiesObject
? GSON_PROPERTIES.fromJson(userPropertiesObject, JsonUtils.mapTypeOf(String.class, String.class))
: null;
return new YggdrasilSession(clientToken, accessToken, new GameProfile(profileID, profileName), null, userProperties);
}
public void writePrivateData(JsonObject privateData) {
if (selectedProfile == null)
throw new IllegalStateException("No character is selected");
privateData.addProperty("clientToken", clientToken);
privateData.addProperty("accessToken", accessToken);
privateData.addProperty("profileName", selectedProfile.getName());
privateData.add("userProperties", GSON_PROPERTIES.toJsonTree(userProperties));
}
private static String requireStorageString(JsonObject storage, String name) {
String value = JsonUtils.getString(storage, name);
if (value == null) {
throw new IllegalArgumentException(name + " is missing");
}
return value;
}
public AuthInfo toAuthInfo() {
if (selectedProfile == null)
throw new IllegalStateException("No character is selected");View on GitHub (pinned to 24702dc5a0)