HMCL-dev/HMCL · error · JsonParseException

Type must between

Error message

Type must between [0, %s)

What it means

TerracottaState's typed entry validates that its integer 'type' field indexes into the LOOKUP table (0 <= type < LOOKUP.length). An out-of-range type would otherwise throw ArrayIndexOutOfBoundsException later, so JsonParseException with the allowed range is thrown during validation.

Solutions

  1. Set type to a value within [0, LOOKUP.length) as defined by this HMCL build
  2. Upgrade HMCL to a version whose LOOKUP table includes the declared type
  3. Fix or regenerate the state file instead of hand-editing type ids
  4. Catch JsonParseException and reset the entry to a known-valid type

Example fix

// before
"type": 9
// after
"type": 0
Defensive patterns

Strategy: validation

Validate before calling

int t = entry.get("type").getAsInt(); if (t < 0 || t >= TerracottaState.LOOKUP.length) { throw new IllegalArgumentException("type " + t + " out of range"); }

Type guard

static boolean knownType(int t) { return t >= 0 && t < TerracottaState.LOOKUP.length; }

Try / catch

try { entry.validate(); } catch (JsonParseException e) { LOG.warning("Invalid terracotta type id; resetting", e); }

Prevention

When it happens

Trigger: A state/type entry whose type is negative or >= LOOKUP.length — produced by a newer HMCL version with more types, or corrupted/hand-edited JSON.

Common situations: Downgrading HMCL so newer type ids are unrecognized; manual edits inserting wrong ids; data corruption.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10). Data as JSON: /api/errors/904ef7f89a7cb086. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaState.java:301

            HOST_ET_CRASH,
            PING_SERVER_RST,
            SCAFFOLDING_INVALID_RESPONSE
        }

        private static final TerracottaState.Exception.Type[] LOOKUP = Type.values();

        @SerializedName("type")
        private final int type;

        Exception(int port, int index, String state, int type) {
            super(port, index, state);
            this.type = type;
        }

        @Override
        public void validate() throws JsonParseException, TolerableValidationException {
            if (type < 0 || type >= LOOKUP.length) {
                throw new JsonParseException(String.format("Type must between [0, %s)", LOOKUP.length));
            }
        }

        public Type getType() {
            return LOOKUP[type];
        }
    }

    public static final class Fatal extends TerracottaState {
        public enum Type {
            OS,
            NETWORK,
            INSTALL,
            TERRACOTTA,
            UNKNOWN;
        }

        private final Type type;

View on GitHub (pinned to 24702dc5a0)