HMCL-dev/HMCL · error · IOException

Invalid theme background paint

Error message

Invalid theme background paint: ${value}

What it means

Thrown by parsePaint when a serialized background paint string cannot be parsed by JavaFX's Paint.valueOf. The value must be a valid JavaFX paint expression (named color, hex, rgb(), gradient, etc.); anything else is wrapped in an IOException with the offending value.

Solutions

  1. Use a valid JavaFX paint value, e.g. "#336699", "0x336699ff", "rgb(51,102,153)", or a standard color name.
  2. Test the value with Paint.valueOf in a scratch snippet before putting it in the manifest.
  3. Escape correctly if the string went through JSON (quotes/backslashes must survive JSON parsing).

Example fix

// before
"paint": "rgb (51, 102, 153)" // unparseable
// after
"paint": "rgb(51,102,153)"
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    javafx.scene.paint.Paint.valueOf(value);
} catch (IllegalArgumentException e) {
    throw new IllegalArgumentException("not a valid JavaFX paint: " + value);
}

Try / catch

try {
    exportThemePack(...);
} catch (IOException e) {
    if (e.getMessage().startsWith("Invalid theme background paint")) {
        // surface e.getCause() (IllegalArgumentException) with a paint-format hint
    }
}

Prevention

When it happens

Trigger: Parsing a theme-pack manifest whose background paint field contains a string that makes Paint.valueOf(value) throw IllegalArgumentException.

Common situations: Typos in color names ("gren" instead of "green"); CSS-like values JavaFX cannot parse (missing # in hex, unsupported color functions); empty or placeholder strings; values copied from web CSS that JavaFX rejects.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

    }

    /// Resolves a theme-pack built-in wallpaper ID.
    private static String resolveBuiltinBackgroundId(@Nullable String id) throws IOException {
        String normalizedId = StringUtils.isBlank(id)
                ? BuiltinBackground.FALLBACK.id()
                : id.trim().toLowerCase(Locale.ROOT);
        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)