{"record":{"id":"a62096a2b380369e","repo":"HMCL-dev/HMCL","slug":"primary-jar-source-is-not-a-regular-file-normal","errorCode":null,"errorMessage":"Primary JAR source is not a regular file: ${normalizedSource}","messagePattern":"Primary JAR source is not a regular file: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepositoryDraft.java","lineNumber":134,"sourceCode":"\n    /// {@inheritDoc}\n    @Override\n    public void put(GameInstanceManifest manifest) throws IOException {\n        checkOpen();\n        putManifest(manifest, true);\n    }\n\n    /// {@inheritDoc}\n    @Override\n    public void putPrimaryJar(GameInstanceID instanceId, Path source) throws IOException {\n        checkOpen();\n        if (!manifests.containsKey(instanceId)) {\n            throw new NoSuchGameInstanceException(instanceId);\n        }\n\n        Path normalizedSource = source.toAbsolutePath().normalize();\n        if (!Files.isRegularFile(normalizedSource)) {\n            throw new IOException(\"Primary JAR source is not a regular file: \" + normalizedSource);\n        }\n\n        Path target = getPrimaryJarTarget(instanceId);\n        if (normalizedSource.equals(target)) {\n            primaryJarSources.remove(instanceId);\n        } else {\n            primaryJarSources.put(instanceId, normalizedSource);\n        }\n    }\n\n    /// {@inheritDoc}\n    @Override\n    public void remove(GameInstanceID instanceId) {\n        checkOpen();\n        if (manifests.remove(instanceId) == null) {\n            throw new NoSuchGameInstanceException(instanceId);\n        }\n","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/HMCL-dev/HMCL/blob/24702dc5a0214034f4c27166d5fd30cad08cec19/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepositoryDraft.java#L116-L152","documentation":"After confirming the instance exists, putPrimaryJar() normalizes the source path and requires it to be a regular file on disk. If not, it throws IOException('Primary JAR source is not a regular file: <path>'). This guards against committing directories, symlinks to nothing, or nonexistent paths as an instance's primary jar.","triggerScenarios":"Passing a directory, a dangling symlink, or a path that does not exist (e.g. jar not yet downloaded/extracted) as the source to putPrimaryJar; also passing a relative path that resolves outside the expected location after normalization.","commonSituations":"Automated flows that assume a downloaded jar exists without checking; copying install scripts between machines where the jar lives at a different path; races where a temp jar is deleted before commit.","solutions":["Check Files.isRegularFile(normalizedPath) before calling putPrimaryJar and download/extract the jar if missing","Ensure the source path is absolute and points at the actual .jar file, not its containing directory","Catch this IOException and report the exact path to the user so they can fix the source location","Fix any producer step (download/copy) so it completes before staging the primary jar"],"exampleFix":"// before\ndraft.putPrimaryJar(instanceId, Paths.get(\"downloads\", \"mc.jar\"));\n// after\nPath jar = Paths.get(\"downloads\", \"mc.jar\").toAbsolutePath().normalize();\nif (!Files.isRegularFile(jar)) {\n    throw new IOException(\"Missing primary jar, run download first: \" + jar);\n}\ndraft.putPrimaryJar(instanceId, jar);","handlingStrategy":"validation","validationCode":"Path src = source.toAbsolutePath().normalize();\nif (!Files.isRegularFile(src)) {\n    throw new IllegalArgumentException(\"Not a jar file: \" + src);\n}","typeGuard":null,"tryCatchPattern":"try {\n    draft.putPrimaryJar(instanceId, source);\n} catch (IOException e) {\n    LOG.warning(\"Primary jar source invalid: \" + e.getMessage());\n}","preventionTips":["Download/extract the jar fully before staging it","Always pass absolute, normalized paths","Check Files.isRegularFile (not just exists) — directories pass exists()"],"tags":["file-not-found","invalid-path","minecraft-instance"],"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"}