{"record":{"id":"3a15e1c62a2385c4","repo":"HMCL-dev/HMCL","slug":"cannot-delete-a-built-in-theme-pack","errorCode":null,"errorMessage":"Cannot delete a built-in theme pack: ","messagePattern":"Cannot delete a built-in theme pack: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java","lineNumber":538,"sourceCode":"                deleteIfExists(temporaryFile);\n            } catch (IOException suppressed) {\n                e.addSuppressed(suppressed);\n            }\n            throw e;\n        }\n    }\n\n    /// Removes an installed theme pack from a managed theme-pack directory.\n    ///\n    /// If the removed package is currently selected, the stored theme reference is cleared.\n    ///\n    /// @param themePack the installed theme pack to remove\n    /// @throws IOException if the installed package cannot be removed\n    public static void uninstall(InstalledThemePack themePack) throws IOException {\n        Objects.requireNonNull(themePack);\n\n        if (themePack.builtin()) {\n            throw new IOException(\"Cannot delete a built-in theme pack: \" + themePack.manifest().id());\n        }\n\n        @Nullable Path file = themePack.file();\n        if (file == null) {\n            throw new IOException(\"Theme pack does not have a local file: \" + themePack.manifest().id());\n        }\n\n        Path targetFile = file.toAbsolutePath().normalize();\n        Path localDirectory = THEME_PACKS_DIRECTORY.toAbsolutePath().normalize();\n        Path userDirectory = USER_THEME_PACKS_DIRECTORY.toAbsolutePath().normalize();\n        boolean localThemePack = targetFile.startsWith(localDirectory) && !targetFile.equals(localDirectory);\n        boolean userThemePack = targetFile.startsWith(userDirectory) && !targetFile.equals(userDirectory);\n        if (!localThemePack && !userThemePack) {\n            throw new IOException(\"Theme-pack file is outside the managed directory: \" + targetFile);\n        }\n\n        deleteIfExists(targetFile);\n","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java#L520-L556","documentation":"ThemePackManager.uninstall(InstalledThemePack) refuses to remove packs flagged as built-in (bundled with the launcher resources). It throws this IOException carrying the pack's manifest id, because built-in packs have no deletable on-disk file managed by the launcher.","triggerScenarios":"Calling ThemePackManager.uninstall() with an InstalledThemePack whose builtin() flag is true, i.e. any pack returned by loadBuiltinThemePacks() rather than installed into THEME_PACKS_DIRECTORY/USER_THEME_PACKS_DIRECTORY.","commonSituations":"UI code iterating all installed packs (including built-ins) and offering a delete action without filtering; scripted cleanup that deletes every pack in the list.","solutions":["Check themePack.builtin() before calling uninstall and skip/exclude built-in packs from deletion.","If the goal is to stop using a built-in pack, switch the selected theme to another pack instead of uninstalling it.","Filter the pack list with p -> !p.builtin() wherever uninstall/delete actions are exposed."],"exampleFix":"// before\nfor (InstalledThemePack p : packs) ThemePackManager.uninstall(p);\n// after\nfor (InstalledThemePack p : packs) {\n    if (!p.builtin()) ThemePackManager.uninstall(p);\n}","handlingStrategy":"type-guard","validationCode":"if (pack.builtin()) return; // nothing to delete; switch theme instead","typeGuard":"static boolean uninstallable(InstalledThemePack p) {\n    return !p.builtin() && p.file() != null;\n}","tryCatchPattern":"try {\n    ThemePackManager.uninstall(pack);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Cannot delete a built-in theme pack\")) {\n    // built-in packs are immutable; ignore or inform the user\n    }\n}","preventionTips":["Filter pack lists with !builtin() before offering delete actions","Treat built-in packs as read-only vocabulary, not user data","To stop using a built-in pack, switch the selected theme instead"],"tags":["theme-pack","uninstall","built-in","guard"],"backgroundTag":"unsupported-operation","analyzedSha":"24702dc5a0214034f4c27166d5fd30cad08cec19","analyzedAt":"2026-09-10T12:36:46.680Z","contentChangedAt":"2026-09-10T12:36:46.680Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}