HMCL-dev/HMCL · error · IllegalArgumentException
is missing
Error message
is missing
What it means
Helper requireStorageString throws '<name> is missing' when a required string ('clientToken' or 'accessToken') is absent from the stored private data JSON. It enforces that persisted credentials needed to rebuild a YggdrasilSession are present.
Solutions
- Re-add the missing 'clientToken'/'accessToken' key to the private data JSON
- Remove the corrupt account entry and log in again to regenerate credentials
- Restore the storage file from backup
Example fix
// before
String token = requireStorageString(privateData, "accessToken"); // throws if absent
// after
if (JsonUtils.getString(privateData, "accessToken") == null) {
privateData = reloginAndRebuildPrivateData();
}
String token = requireStorageString(privateData, "accessToken"); Defensive patterns
Strategy: validation
Validate before calling
for (String key : List.of("clientToken", "accessToken"))
if (JsonUtils.getString(privateData, key) == null)
throw new IllegalArgumentException("Private data missing " + key); Type guard
static boolean hasCredentials(JsonObject privateData) {
return JsonUtils.getString(privateData, "clientToken") != null
&& JsonUtils.getString(privateData, "accessToken") != null;
} Try / catch
try {
session = YggdrasilSession.fromStorage(metadata, privateData);
} catch (IllegalArgumentException e) {
LOG.warning("Missing stored credential: " + e.getMessage());
session = relogin();
} Prevention
- Guard against truncated writes of the storage file (atomic write + rename)
- Validate credential fields when loading accounts before use
- Re-authenticate instead of hand-restoring tokens
When it happens
Trigger: Calling fromStorage whose privateData JsonObject lacks 'clientToken' or 'accessToken', so requireStorageString returns null and throws with the field name plus ' is missing'.
Common situations: Hand-edited or truncated accounts.json, partial writes on crash, or external tools stripping credential fields.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- profileID is missing
- accountID is missing
- Fabric metadata is invalid
- ForgeVersion files cannot be null
- ForgeVersion mcversion cannot be null
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/69febeacc059ba01.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/auth/yggdrasil/YggdrasilSession.java:115
? 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");
return new AuthInfo(selectedProfile.getName(), selectedProfile.getId(), accessToken, AuthInfo.USER_TYPE_MSA,
Optional.ofNullable(userProperties)
.map(properties -> properties.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> Collections.singleton(e.getValue()))))
.map(GSON_PROPERTIES::toJson).orElse("{}"));
}
private static final Gson GSON_PROPERTIES = new Gson();
}View on GitHub (pinned to 24702dc5a0)