HMCL-dev/HMCL · error · JsonParseException
code is null
Error message
code is null
What it means
TerracottaState.State.validate enforces that the required 'code' member is present after JSON deserialization; a missing code means the state object is incomplete and cannot be used, so JsonParseException is thrown.
Solutions
- Add the required 'code' field to the state JSON
- Regenerate the terracotta state through the normal flow instead of editing the file manually
- Restore the file from backup if it was truncated
- Catch JsonParseException at load and re-initialize the terracotta state
Example fix
// before
{"profiles":[...]}
// after
{"code":"AUTH-CODE","profiles":[...]} Defensive patterns
Strategy: type-guard
Validate before calling
if (parsedState.get("code") == null || parsedState.get("code").isJsonNull()) { throw new IllegalArgumentException("state.code required"); } Type guard
static boolean hasNonNull(JsonObject o, String key) { return o.has(key) && !o.get(key).isJsonNull(); } Try / catch
try { state.validate(); } catch (JsonParseException e) { /* re-run terracotta setup to regenerate state */ } Prevention
- Never omit required fields when serializing state
- Use the library's write path for state files
- Validate after every manual or scripted edit
When it happens
Trigger: Deserializing a terracotta state JSON that omits the code field — truncated file, older schema, or hand-edited config.
Common situations: Hand-editing the terracotta state file; version/schema drift dropping the code field; partial writes.
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
- authlib-injectors.json -> urls cannot be null.
- Missing protected payload member: protection
- profiles is null
- Account private data is not an object
- Game directory ID cannot be null
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/1f6b7616ccf19c78.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaState.java:191
private final String code;
@SerializedName("profile_index")
private final int profileIndex;
@SerializedName("profiles")
private final List<TerracottaProfile> profiles;
HostOK(int port, int index, String state, String code, int profileIndex, List<TerracottaProfile> profiles) {
super(port, index, state);
this.code = code;
this.profileIndex = profileIndex;
this.profiles = profiles;
}
@Override
public void validate() throws JsonParseException, TolerableValidationException {
if (code == null) {
throw new JsonParseException("code is null");
}
if (profiles == null) {
throw new JsonParseException("profiles is null");
}
}
public String getCode() {
return code;
}
public List<TerracottaProfile> getProfiles() {
return profiles;
}
@Override
public boolean isForkOf(TerracottaState state) {
return state instanceof HostOK hostOK && this.index - hostOK.index <= profileIndex;
}View on GitHub (pinned to 24702dc5a0)