HMCL-dev/HMCL · error · IOException

Built-in theme-pack asset is missing

Error message

Built-in theme-pack asset is missing: ${entryName}

What it means

BuiltInThemePackResource.openStream reads a classpath resource via getResourceAsStream(resourcePath); a null result means the built-in pack's asset is absent from the classpath/Jar, so it throws IOException "Built-in theme-pack asset is missing: <entryName>". This indicates a broken or stripped installation rather than user data.

Solutions

  1. Re-download or rebuild HMCL with resources included (check the jar contains the built-in theme asset paths).
  2. Verify resourcePath matches the actual classpath location of the asset.
  3. Check build/packaging configuration so resource files are not excluded from the jar.

Example fix

// build.gradle exclusion dropping resources
exclude '**/*.png'
// after
// remove the exclude so theme assets ship in the jar
Defensive patterns

Strategy: fallback

Validate before calling

boolean available = ThemePackResource.class.getResource(resourcePath) != null;

Try / catch

try (InputStream in = resource.openStream()) { use(in); } catch (IOException e) { loadFallbackTheme(); }

Prevention

When it happens

Trigger: The HMCL jar was built/packaged without the built-in theme resource files; resourcePath differs from the packaged location; running from a partially extracted distribution.

Common situations: Custom or minimal builds excluding resource directories; shading/assembly plugins dropping non-class resources; antivirus or deployment tooling stripping files from the jar.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackResource.java:161

        /// @param resourcePath the classpath resource path
        /// @param entryName    the theme-pack entry name
        public Builtin {
            resourcePath = Objects.requireNonNull(resourcePath);
            entryName = ThemePackAsset.normalizeEntryName(entryName);
        }

        /// Returns the theme-pack entry name.
        @Override
        public String name() {
            return entryName;
        }

        /// Opens the classpath resource.
        @Override
        public InputStream openStream() throws IOException {
            @Nullable InputStream input = ThemePackResource.class.getResourceAsStream(resourcePath);
            if (input == null) {
                throw new IOException("Built-in theme-pack asset is missing: " + entryName);
            }
            return input;
        }
    }

    /// An input stream that owns a zip file handle.
    @NotNullByDefault
    final class ZipEntryInputStream extends FilterInputStream {
        /// The zip file that must stay open while this stream is read.
        private final ZipArchiveReader zipFile;

        /// Whether this stream has already been closed.
        private boolean closed;

        /// Creates a zip-entry stream.
        ///
        /// @param input   the zip entry input stream
        /// @param zipFile the owning zip file

View on GitHub (pinned to 24702dc5a0)