HMCL-dev/HMCL · error · IOException

Theme packs cannot reference built-in wallpaper

Error message

Theme packs cannot reference built-in wallpaper: ${normalizedId}

What it means

Thrown when parsing a theme-pack manifest whose background id resolves to a built-in wallpaper identifier. Built-in backgrounds are launcher-internal, so theme packs must not reference them; only custom ids declared by the pack itself are allowed.

Solutions

  1. Rename the background id in the manifest to a custom, non-built-in identifier unique to the pack.
  2. Remove the built-in background reference and declare an image/paint background instead.
  3. Check BuiltinBackground ids (e.g. the fallback id) and avoid any of them as theme-pack background ids.

Example fix

// before
{ "background": { "type": "builtin", "id": "default" } }
// after
{ "background": { "type": "image", "id": "my-pack-wallpaper", "path": "assets/wallpapers/wall.png" } }
Defensive patterns

Strategy: validation

Validate before calling

String normalized = (id == null || id.isBlank()) ? "fallback" : id.trim().toLowerCase(Locale.ROOT);
if (BuiltinBackground.fromId(normalized) != null) {
    throw new IllegalArgumentException("use a custom background id, not a built-in one: " + normalized);
}

Prevention

When it happens

Trigger: Reading a theme-pack manifest where the background id (after trim().toLowerCase(Locale.ROOT), or FALLBACK when blank) matches a known BuiltinBackground id, so BuiltinBackground.fromId(normalizedId) != null.

Common situations: Manifest author writes "id": "default" or another built-in wallpaper name thinking it selects the launcher default; copying background config from an ordinary theme settings file into a pack manifest; blank id normalizing to the built-in fallback id.

Related errors


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

Appendix: source

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

        return SettingsManager.settings().getThemeAppearanceOverrides().contains(LauncherSettings.THEME_APPEARANCE_BACKGROUND_OPACITY)
                ? currentBackgroundOpacity()
                : 1.0;
    }

    /// Returns the currently selected built-in wallpaper ID.
    private static String currentBuiltinBackgroundId() {
        return BuiltinBackground.fromIdOrFallback(settings().builtinBackgroundIdProperty().get()).id();
    }

    /// 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();
    }

View on GitHub (pinned to 24702dc5a0)