HMCL-dev/HMCL · error · IOException

Theme pack value is missing

Error message

Theme pack value is missing: ${name}

What it means

Thrown by requireNonBlank, the shared validator for mandatory theme-pack string values, when a required manifest value is null, empty, or whitespace-only. The message names the missing field so the manifest author can locate it.

Solutions

  1. Fill in the named manifest field with a non-blank value (the message tells you which key, e.g. background.url).
  2. Remove surrounding whitespace or stray quotes/commas that leave the value empty after JSON parsing.
  3. Validate the manifest JSON for empty strings before loading it into the launcher.

Example fix

// before
"background": { "url": "" }
// after
"background": { "url": "https://example.com/wall.png" }
Defensive patterns

Strategy: validation

Validate before calling

static void requireNonBlank(String v, String name) {
    if (v == null || v.isBlank()) throw new IllegalArgumentException(name + " must be a non-blank string");
}

Prevention

When it happens

Trigger: Any theme-pack parse/resolve path calling requireNonBlank(value, name) — e.g. background.networkImageUrl with "background.url" — where the value is blank.

Common situations: Manifest keys present but with empty string values ("url": ""); whitespace-only values after copy/paste; fields omitted entirely then read as null; template placeholders like "<your-url-here>" left unfilled would not trigger this (not blank) but empty ones will.

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/089b38e87f7b0309. Report an issue: GitHub.

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java:1609

        if (BuiltinBackground.fromId(normalizedId) != null) {
            return normalizedId;
        }
        throw new IOException("Theme packs cannot reference built-in wallpaper: " + normalizedId);
    }

    /// Parses a serialized JavaFX paint value.
    private static Paint parsePaint(String value) throws IOException {
        try {
            return Paint.valueOf(value);
        } catch (IllegalArgumentException e) {
            throw new IOException("Invalid theme background paint: " + value, e);
        }
    }

    /// Returns a non-blank string value.
    private static String requireNonBlank(@Nullable String value, String name) throws IOException {
        if (StringUtils.isBlank(value)) {
            throw new IOException("Theme pack value is missing: " + name);
        }
        return value.trim();
    }

    /// Sanitizes one path segment used for exported asset files.
    private static String sanitizePathSegment(String value) {
        String sanitized = value.trim().replaceAll("[^A-Za-z0-9._-]", "_");
        if (sanitized.isBlank()) {
            return "_";
        }
        return sanitized;
    }
}

View on GitHub (pinned to 24702dc5a0)