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
- Verify the wallpaper file is a valid, decodable PNG/JPG and re-save/export it with an image tool
- Check that the resource path/name points to an actually bundled image (resource.openStream() succeeded, decoding failed)
- Catch IOException at the call site and fall back to a default wallpaper / fallback theme color
- 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
- Always pass a decodable PNG/JPG as wallpaper resource
- Probe-decode the image once at startup and cache the result
- Keep a bundled default wallpaper as fallback
- Re-verify bundled resources after packaging
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
- Failed to load JavaFX cache
- Theme-pack asset source is not a regular file:
- Theme pack directory does not contain
- Theme pack does not contain
- Invalid theme-pack manifest
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)