HMCL-dev/HMCL · error · JsonParseException

Invalid JSON schema

Error message

Invalid JSON schema 

What it means

JsonSchema.parseElement expects the JSON element representing a schema to be a string primitive. This JsonParseException is thrown when the element is missing, null, an object, array, number, or boolean.

Solutions

  1. Ensure the JSON contains the schema field as a quoted string (a schema URL).
  2. Inspect the JSON source for an upstream format change and update the parsing code or pin a compatible source.
  3. Validate the JSON structure before deserialization (check the member exists and isString()).
  4. If the field is optional, handle its absence before calling code that parses the schema.

Example fix

// before
{"schema": {"version": 2}}
// after
{"schema": "https://hmcl.example/schemas/v2.json"}
Defensive patterns

Strategy: validation

Validate before calling

JsonElement el = JsonParser.parseString(json);
JsonElement schema = el.getAsJsonObject().get("schema");
if (schema == null || !schema.isJsonPrimitive() || !schema.getAsString().startsWith("http"))
    throw new IllegalArgumentException("Missing or invalid schema string");

Type guard

static boolean hasStringSchema(JsonObject obj) {
    JsonElement e = obj.get("schema");
    return e != null && e.isJsonPrimitive() && e.getAsJsonPrimitive().isString();
}

Try / catch

try {
    return readDocument(json);
} catch (JsonParseException e) {
    log.error("Document schema invalid: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Reading a JSON document whose schema field is absent or not a string (e.g. an embedded object or a number), via readFromMember-driven deserialization.

Common situations: Server/download-index JSON that embeds the schema as an object instead of a URL string, schema field renamed or removed upstream, or a truncated response.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/JsonSchema.java:174

        if (actualParsed.version().major() != expectedParsed.version().major()) {
            return CompatibilityResult.unsupportedMajor(actual);
        }

        if (actualParsed.version().minor() > expectedParsed.version().minor()) {
            return CompatibilityResult.readOnlyPreserveSchema(actual);
        }

        if (actualParsed.version().minor() == expectedParsed.version().minor()) {
            return CompatibilityResult.readWritePreserveSchema(actual);
        }

        return CompatibilityResult.readWrite(actual);
    }

    /// Parses a schema string from a JSON element.
    private static JsonSchema parseElement(@Nullable JsonElement element, String source) throws JsonParseException {
        if (!(element instanceof JsonPrimitive primitive) || !primitive.isString()) {
            throw new JsonParseException("Invalid JSON schema " + source + ": " + element);
        }

        return new JsonSchema(primitive.getAsString());
    }

    /// Parses an HMCL schema URL, returning `null` for any other string.
    private static @Nullable Parsed parseSchemaUrl(String value) {
        Objects.requireNonNull(value);

        if (!value.startsWith(URL_PREFIX)) {
            return null;
        }

        String path = value.substring(URL_PREFIX.length());
        int slash = path.indexOf('/');
        if (slash <= 0 || slash != path.lastIndexOf('/') || slash == path.length() - 1) {
            return null;
        }

View on GitHub (pinned to 24702dc5a0)