HMCL-dev/HMCL · error · JsonParseException

Theme background field is missing:

Error message

Theme background field is missing: 

What it means

ThemeBackground.requireNonBlank throws this JsonParseException when a required source field is absent (null) while constructing a Builtin, Image, or Paint background. It fires when a constructor receives a null value for its mandatory field — e.g. {"type":"image"} with no "path" — because the record's compact constructor delegates to requireNonBlank.

Solutions

  1. Add the required field for the declared type: "id" for builtin, "path" for image, "paint" for paint
  2. Use type "default" or "theme_color" instead if no concrete source value exists
  3. For programmatic construction, pass a non-null string or use the no-arg Builtin() fallback constructor

Example fix

// before
{"type": "image"}
// after
{"type": "image", "path": "assets/bg.png"}
Defensive patterns

Strategy: validation

Validate before calling

if (obj.has("type")) {
    String t = obj.get("type").getAsString().toUpperCase(Locale.ROOT);
    String need = switch (t) { case "IMAGE" -> "path"; case "PAINT" -> "paint"; case "BUILTIN" -> "id"; default -> null; };
    if (need != null && !obj.has(need)) throw new IllegalArgumentException("missing field for type " + t + ": " + need);
}

Try / catch

try { ThemeBackground.fromJson(obj); } catch (JsonParseException e) { LOG.warning("Background field missing: " + e.getMessage()); }

Prevention

When it happens

Trigger: fromJson on {"type":"builtin"} with no "id" only if code passes null to the Builtin(String) constructor path requiring it — concretely, constructing new Image(null), new Paint(null), or new Builtin with a null id via a code path that requires it, or JSON like {"type":"image"} where path resolves to null for the Image record constructor.

Common situations: Theme manifests where the "type" was set but the matching value field was forgotten ({"type":"image"} with no "path"), or programmatic construction of records with null required arguments.

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


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemeBackground.java:128

        };
    }

    /// Reads an optional string field.
    private static @Nullable String readString(JsonObject object, String field) {
        JsonElement element = object.get(field);
        if (element == null) {
            return null;
        }
        if (!(element instanceof JsonPrimitive primitive) || !primitive.isString()) {
            throw new JsonParseException("Theme background field must be a string: " + field);
        }
        return primitive.getAsString();
    }

    /// Returns a required non-blank string value.
    private static String requireNonBlank(@Nullable String value, String field) {
        if (value == null) {
            throw new JsonParseException("Theme background field is missing: " + field);
        }
        String trimmed = value.trim();
        if (trimmed.isEmpty()) {
            throw new JsonParseException("Theme background field is blank: " + field);
        }
        return trimmed;
    }

    /// A source that delegates to HMCL's launcher default background resolution.
    @NotNullByDefault
    record Default() implements ThemeBackground {
        /// Adds this source to a JSON object.
        @Override
        public void addToJsonObject(JsonObject object) {
            object.addProperty(FIELD_TYPE, "default");
        }

    }

View on GitHub (pinned to 24702dc5a0)