{"record":{"id":"8f5b4a46837f33c4","repo":"HMCL-dev/HMCL","slug":"theme-pack-asset-source-is-not-a-regular-file","errorCode":null,"errorMessage":"Theme-pack asset source is not a regular file: ","messagePattern":"Theme-pack asset source is not a regular file: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackExporter.java","lineNumber":105,"sourceCode":"            try {\n                Files.deleteIfExists(temporaryFile);\n            } catch (IOException suppressed) {\n                e.addSuppressed(suppressed);\n            }\n            throw e;\n        }\n    }\n\n    /// Validates all asset entries and source files before the zip is written.\n    private static void validateAssets(List<ThemePackAsset> assets) throws IOException {\n        Set<String> entries = new HashSet<>();\n        entries.add(MANIFEST_ENTRY);\n\n        for (ThemePackAsset asset : assets) {\n            Objects.requireNonNull(asset);\n            @Nullable Path sourceFile = asset.source().file();\n            if (sourceFile != null && !Files.isRegularFile(sourceFile)) {\n                throw new IOException(\"Theme-pack asset source is not a regular file: \" + sourceFile);\n            }\n            try (InputStream ignored = asset.source().openStream()) {\n                // Validate readability before writing the target zip.\n            }\n            if (!entries.add(asset.entryName())) {\n                throw new IllegalArgumentException(\"Duplicate theme-pack zip entry: \" + asset.entryName());\n            }\n        }\n    }\n}\n","sourceCodeStart":87,"sourceCodeEnd":116,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackExporter.java#L87-L116","documentation":"Thrown by ThemePackExporter.validateAssets (invoked from export) when an asset's declared source path exists but is not a regular file — typically a directory. Exporting would otherwise zip a non-file source, so the exporter validates every asset source and its readability before the target archive is written.","triggerScenarios":"Calling ThemePackExporter.export with a ThemePackAsset whose source().file() points to a directory (or special file like a socket/fifo) instead of a regular file.","commonSituations":"Pointing a background asset at a directory of wallpapers instead of a single image, resolving paths through symlinks to directories, or build scripts passing a folder where a file is expected.","solutions":["Change the asset source to point to an actual file, not a directory.","If a directory was intended, enumerate it and create one ThemePackAsset per file.","Verify with Files.isRegularFile(path) before building the asset list.","Check symlink targets — resolve to the final target and confirm it is a regular file."],"exampleFix":"// before\nvar asset = ThemePackAsset.of(\"background.png\", Path.of(\"assets/wallpapers\"));\n// after\nvar asset = ThemePackAsset.of(\"background.png\", Path.of(\"assets/wallpapers/default.png\"));","handlingStrategy":"validation","validationCode":"for (ThemePackAsset a : assets) {\n    Path f = a.source().file();\n    if (f != null && !Files.isRegularFile(f)) {\n        throw new IllegalArgumentException(\"Not a regular file: \" + f);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { ThemePackExporter.export(pack, assets, out); } catch (IOException e) { if (e.getMessage().startsWith(\"Theme-pack asset source is not a regular file\")) fixAssetPaths(); throw e; }","preventionTips":["Call Files.isRegularFile on every asset source before export","Point assets at single files, never directories","Resolve symlinks to their final target and re-check"],"tags":["io","theme-pack","export","file-validation"],"backgroundTag":"incompatible-source-type","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"}