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

  1. Select a character first (set the selected profile) before calling writePrivateData
  2. Check selectedProfile != null and skip/persist as partial state instead of throwing
  3. 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

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)