{"record":{"id":"452982eb312dc594","repo":"HMCL-dev/HMCL","slug":"installed-theme-pack-asset-is-missing","errorCode":null,"errorMessage":"Installed theme-pack asset is missing: ","messagePattern":"Installed theme-pack asset is missing: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java","lineNumber":1215,"sourceCode":"    public static ThemePackResource resolveInstalledAsset(ThemePackLocation location, String entryName) throws IOException {\n        Objects.requireNonNull(location);\n        String normalizedEntryName = ThemePackAsset.normalizeEntryName(entryName);\n        if (location instanceof ThemePackLocation.Builtin builtin) {\n            return resolveBuiltinAsset(builtin, normalizedEntryName);\n        }\n\n        @Nullable Path file = location.file();\n        if (file == null) {\n            throw new IOException(\"Theme pack location has no readable file: \" + location);\n        }\n        Path installedFile = file.toAbsolutePath().normalize();\n        if (Files.isDirectory(installedFile)) {\n            Path assetFile = installedFile.resolve(normalizedEntryName).normalize();\n            if (!assetFile.startsWith(installedFile)) {\n                throw new IOException(\"Theme-pack asset escapes the installed directory: \" + normalizedEntryName);\n            }\n            if (!Files.isRegularFile(assetFile)) {\n                throw new IOException(\"Installed theme-pack asset is missing: \" + normalizedEntryName);\n            }\n            return new ThemePackResource.File(assetFile, normalizedEntryName);\n        }\n        if (!Files.isRegularFile(installedFile)) {\n            throw new IOException(\"Installed theme-pack file is missing: \" + installedFile);\n        }\n\n        try (ZipArchiveReader zipFile = new ZipArchiveReader(installedFile, StandardCharsets.UTF_8)) {\n            ZipArchiveEntry entry = zipFile.getEntry(normalizedEntryName);\n            if (entry == null || entry.isDirectory()) {\n                throw new IOException(\"Installed theme-pack asset is missing: \" + normalizedEntryName);\n            }\n        }\n        return new ThemePackResource.Zip(installedFile, normalizedEntryName);\n    }\n\n    /// Resolves one asset stored in a bundled theme pack.\n    private static ThemePackResource resolveBuiltinAsset(ThemePackLocation.Builtin builtin, String entryName) throws IOException {","sourceCodeStart":1197,"sourceCodeEnd":1233,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java#L1197-L1233","documentation":"When the theme-pack location is a directory, resolveInstalledAsset resolves the normalized entry inside it and requires the target to be a regular file. If the resolved asset path does not exist or is not a regular file (e.g. a directory), it throws this IOException naming the entry.","triggerScenarios":"Calling resolveInstalledAsset() on a directory-installed pack where the referenced entry is absent from the unpacked directory, was deleted, or resolves to a subdirectory rather than a file.","commonSituations":"A manifest referencing assets renamed in a newer pack version; the user manually deleting files from the unpacked pack directory; case-sensitivity mismatches on Linux after a pack created on Windows.","solutions":["Verify the asset exists at <packDir>/<entryName> and is a regular file before resolving.","Reinstall or re-export the theme pack so the manifest and its assets are in sync.","Fix entry-name case to match the on-disk file, especially on case-sensitive filesystems."],"exampleFix":"// before\nresolveInstalledAsset(location, manifest.getBackgroundEntry());\n// after\nPath asset = Path.of(packDir, entry);\nif (Files.isRegularFile(asset)) resolveInstalledAsset(location, entry);","handlingStrategy":"validation","validationCode":"Path asset = Path.of(packDir, ThemePackAsset.normalizeEntryName(entryName));\nif (!Files.isRegularFile(asset)) {\n    // skip or re-export the pack; do not resolve\n}","typeGuard":null,"tryCatchPattern":"try {\n    ThemePackManager.resolveInstalledAsset(location, entry);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Installed theme-pack asset is missing\")) {\n    // fall back to a default asset or prompt reinstall\n    }\n}","preventionTips":["Reinstall packs whose unpacked directory was modified or partially deleted","Verify manifest entry names match on-disk filenames (watch case sensitivity)","Treat directory-installed packs as managed: do not edit files inside them"],"tags":["theme-pack","assets","missing-file","directory-pack"],"backgroundTag":"file-not-found","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}