HMCL-dev/HMCL · error · IllegalArgumentException

${value}

Error message

${value}

What it means

`GameVersionNumber.LegacySnapshot.parse` throws `IllegalArgumentException(value)` when the 2-digit year or 2-digit week portion of a legacy snapshot id (`YYwWWx`) is not numeric — `Integer.parseInt` throws `NumberFormatException`, caught and rethrown as `IllegalArgumentException` with the original value. Note the year must also be below `MINIMUM_YEAR_MAJOR_VERSION`; years that high indicate a snapshot from the modern era that this legacy format does not cover (handled at line 669).

Solutions

  1. Ensure characters 0-1 and 3-4 are decimal digits, e.g. validate with regex `\d{2}w\d{2}[a-z](_unobfuscated)?` before parsing.
  2. Replace placeholder or corrupted fields with the actual numeric year/week values.
  3. If the year is >= MINIMUM_YEAR_MAJOR_VERSION, the id is not a legacy snapshot — parse it as a modern Release version instead.

Example fix

// before
GameVersionNumber.parse("YYwWWa"); // throws
// after
if (version.matches("\\d{2}w\\d{2}[a-z](_unobfuscated)?")) {
    GameVersionNumber.parse(version);
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean snapshotFieldsAreNumeric(String v) {
    return v != null && v.matches("\\d{2}w\\d{2}[a-z](_unobfuscated)?");
}
if (!snapshotFieldsAreNumeric(id)) throw new IllegalArgumentException("bad snapshot id: " + id);

Try / catch

try {
    GameVersionNumber.parse(id);
} catch (IllegalArgumentException e) {
    log.error("Snapshot id has non-numeric year/week fields: {}", id);
    // reject or prompt user for the correct id
}

Prevention

When it happens

Trigger: Strings of the exact shape `??w??x` (6 chars, 'w' at index 2, prefix length 6) where positions 0-1 or 3-4 are non-digits, e.g. "1.w46a", "18w4.a", "abw46a". Also fires when the parsed year is >= the minimum year major version constant.

Common situations: Snapshot ids with letters accidentally in the numeric fields ("1Aw46a"), placeholder strings like "YYwWWa" from documentation, or new-style yearly versions (year >= MINIMUM_YEAR_MAJOR_VERSION) mistakenly formatted as legacy snapshots.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/versioning/GameVersionNumber.java:666

                unobfuscated = true;
                normalized = value.substring(0, prefixLength) + "_unobfuscated";
            } else {
                prefixLength = value.length();
                unobfuscated = false;
                normalized = value;
            }

            if (prefixLength != 6) {
                throw new IllegalArgumentException(value);
            }

            int year;
            int week;
            try {
                year = Integer.parseInt(value, 0, 2, 10);
                week = Integer.parseInt(value, 3, 5, 10);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException(value);
            }

            if (year >= Release.MINIMUM_YEAR_MAJOR_VERSION) {
                throw new IllegalArgumentException(value);
            }

            char suffix = value.charAt(5);
            if (suffix < 'a' || suffix > 'z')
                throw new IllegalArgumentException(value);

            return new LegacySnapshot(value, normalized, year, week, suffix, unobfuscated);
        }

        static int toInt(int year, int week, char suffix, boolean unobfuscated) {
            return (year << 24) | (week << 16) | (suffix << 8) | (unobfuscated ? 1 : 0);
        }

        final int intValue;

View on GitHub (pinned to 24702dc5a0)