HMCL-dev/HMCL · error · IOException

Failed to load wallpaper image:

Error message

Failed to load wallpaper image: 

What it means

Thrown by WallpaperColorExtractor.extract(ResourceNotFoundException-style resource wrapper) when FXUtils.loadImage fails to decode a wallpaper image from the resource stream with an exception that is not an IOException (e.g. image decoding/JavaFX errors). The original resource name is wrapped so the caller knows which wallpaper failed.

Solutions

  1. Verify the wallpaper file is a valid, decodable PNG/JPG and re-save/export it with an image tool
  2. Check that the resource path/name points to an actually bundled image (resource.openStream() succeeded, decoding failed)
  3. Catch IOException at the call site and fall back to a default wallpaper / fallback theme color
  4. Reinstall or repack HMCL if a bundled wallpaper resource is corrupt

Example fix

// before
ThemeColor color = wallpaperColorExtractor.extract(resource, fallback);
// after
ThemeColor color;
try {
    color = wallpaperColorExtractor.extract(resource, fallback);
} catch (IOException e) {
    LOG.warning("Wallpaper failed to load, using fallback color", e);
    color = fallback;
}
Defensive patterns

Strategy: try-catch

Validate before calling

Path p = Paths.get("wallpaper.png");
if (!Files.isRegularFile(p) || Files.size(p) == 0) { /* use default wallpaper */ }
try (var in = Files.newInputStream(p)) { new javafx.scene.image.Image(in).getWidth(); } // probe decodability

Type guard

static boolean isDecodableImage(java.io.InputStream in) {
    Image img = new Image(in, 0, 0, true, true, true);
    return !img.isError();
}

Try / catch

try {
    color = extractor.extract(resource, fallback);
} catch (IOException e) {
    LOG.warning("Wallpaper load failed: " + e.getMessage(), e);
    color = fallback;
}

Prevention

When it happens

Trigger: Calling WallpaperColorExtractor.extract with a wallpaper resource whose stream cannot be decoded by FXUtils.loadImage — corrupt/unsupported image bytes, JavaFX Image decoding exceptions (non-IOException), e.g. a broken or mis-typed image file set as theme wallpaper.

Common situations: Users selecting a custom wallpaper file that is corrupt, truncated, or in an unsupported format; bundled wallpaper resources damaged or mispackaged in the distribution; environment issues where the JavaFX image loaders are unavailable.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/WallpaperColorExtractor.java:77

    /// Extracts a theme color from a theme-pack resource.
    ///
    /// @param resource the theme-pack resource
    /// @param fallback the fallback color used when extraction fails
    /// @return the extracted color, or `fallback` when no suitable color is found
    /// @throws IOException if the resource cannot be read
    static ThemeColor extract(ThemePackResource resource, ThemeColor fallback) throws IOException {
        Objects.requireNonNull(resource);
        Objects.requireNonNull(fallback);

        Image image;
        try {
            image = FXUtils.loadImage(resource.openStream(), resource.name());
        } catch (Exception e) {
            if (e instanceof IOException ioException) {
                throw ioException;
            }
            throw new IOException("Failed to load wallpaper image: " + resource.name(), e);
        }

        return extract(image, fallback);
    }

    /// Extracts a theme color from a loaded image.
    ///
    /// @param image the loaded image
    /// @param fallback the fallback color used when extraction fails
    /// @return the extracted color, or `fallback` when no suitable color is found
    public static ThemeColor extract(Image image, ThemeColor fallback) {
        Objects.requireNonNull(image);
        Objects.requireNonNull(fallback);

        Color extracted = ColorScheme.extractColor(image, fallback.color());
        return ThemeColor.of(extracted);
    }
}

View on GitHub (pinned to 24702dc5a0)