{"record":{"id":"0cf556b052f7a86f","repo":"Anuken/Mindustry","slug":"invalid-file-no-mod-json-found","errorCode":null,"errorMessage":"Invalid file: No mod.json found.","messagePattern":"Invalid file: No mod\\.json found\\.","errorType":"validation","errorClass":"ModLoadException","httpStatus":null,"severity":"error","filePath":"core/src/mindustry/mod/Mods.java","lineNumber":1097,"sourceCode":"        if(OS.isMac && (!(fi instanceof ZipFi))) fi.child(\".DS_Store\").delete();\n        Fi[] files = fi.list();\n        return files.length == 1 && files[0].isDirectory() ? files[0] : fi;\n    }\n\n    /** Loads a mod file+meta, but does not add it to the list.\n     * Note that directories can be loaded as mods. */\n    private LoadedMod loadMod(Fi sourceFile, boolean overwrite, boolean initialize) throws Exception{\n\n        ZipFi rootZip = null;\n\n        try{\n            Fi zip = resolveRoot(sourceFile.isDirectory() ? sourceFile : (rootZip = new ZipFi(sourceFile)));\n\n            ModMeta meta = findMeta(zip);\n\n            if(meta == null){\n                Log.warn(\"Mod @ doesn't have a '[mod/plugin].[h]json' file, skipping.\", zip);\n                throw new ModLoadException(\"Invalid file: No mod.json found.\");\n            }\n\n            String camelized = meta.name.replace(\" \", \"\");\n            String mainClass = meta.main == null ? camelized.toLowerCase(Locale.ROOT) + \".\" + camelized + \"Mod\" : meta.main;\n            String baseName = meta.name.toLowerCase(Locale.ROOT).replace(\" \", \"-\");\n\n            var other = mods.find(m -> m.name.equals(baseName));\n\n            if(other != null){\n                //steam mods can't really be deleted, they need to be unsubscribed\n                if(overwrite && !other.hasSteamID()){\n\n                    //close the classloader for jar mods\n                    if(!android){\n                        ClassLoaderCloser.close(other.loader);\n                    }else if(other.loader != null){\n                        //Try to remove cache for Android 14 security problem\n                        Fi cacheDir = new Fi(Core.files.getCachePath()).child(\"mods\");","sourceCodeStart":1079,"sourceCodeEnd":1115,"githubUrl":"https://github.com/Anuken/Mindustry/blob/f695ad7e60323ebced984fa26d0bcf0bc54296b4/core/src/mindustry/mod/Mods.java#L1079-L1115","documentation":"loadMod resolves the mod root (zip or directory) and searches for a meta file (mod.json/plugin.hjson etc. via findMeta). If none is present it logs a warning and throws ModLoadException 'Invalid file: No mod.json found.' A mod cannot be loaded without a manifest.","triggerScenarios":"The supplied source file/directory contains no recognized manifest at its root.","commonSituations":"Zipped the parent folder instead of its contents (manifest ends up nested one level deep); wrong filename; manifest named meta.json instead of mod.json; plain data archive loaded as a mod.","solutions":["Ensure mod.json (or plugin.json/plugin.hjson/mod.hjson) exists at the root of the zip/directory.","Re-zip so the manifest is at the archive's top level, not inside a subfolder.","Use the exact expected manifest filename."],"exampleFix":"// before: mymod.zip\n//   mymod/\n//     mod.json\n// (nested -> not found)\n\n// after: mymod.zip\n//   mod.json\n//   ...files...","handlingStrategy":"validation","validationCode":"// Verify a manifest exists at the archive/directory root before importing.\nFi root = resolveRoot(source);\nboolean hasMeta = false;\nfor(String name : new String[]{\"mod.json\",\"mod.hjson\",\"plugin.json\",\"plugin.hjson\"}) {\n    if(root.child(name).exists()){ hasMeta = true; break; }\n}\nif(!hasMeta) throw new ModLoadException(\"Invalid file: No mod.json found.\");","typeGuard":"boolean hasManifest(Fi root){\n    return java.util.List.of(\"mod.json\",\"mod.hjson\",\"plugin.json\",\"plugin.hjson\").stream().anyMatch(n -> root.child(n).exists());\n}","tryCatchPattern":"try {\n    mods.loadMod(file);\n} catch(ModLoadException e) {\n    if(e.getMessage().contains(\"No mod.json\")) { /* fix archive layout */ }\n    else throw e;\n}","preventionTips":["Place mod.json at the zip root, not in a subfolder.","Use the exact expected manifest filename.","Verify archive layout before publishing (unzip -l)."],"tags":["modding","packaging","manifest"],"backgroundTag":null,"analyzedSha":"f695ad7e60323ebced984fa26d0bcf0bc54296b4","analyzedAt":"2026-08-14T04:31:16.262Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}