{"record":{"id":"e683b4478d8e309e","repo":"jenkinsci/jenkins","slug":"no-such-file","errorCode":null,"errorMessage":"No such file: {}","messagePattern":"No such file: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/hudson/ClassicPluginStrategy.java","lineNumber":459,"sourceCode":"    }\n\n    private static void parseClassPath(Manifest manifest, File archive, List<File> paths, String attributeName, String separator) throws IOException {\n        String classPath = manifest.getMainAttributes().getValue(attributeName);\n        if (classPath == null) return; // attribute not found\n        for (String s : classPath.split(separator)) {\n            File file = resolve(archive, s);\n            if (file.getName().contains(\"*\")) {\n                // handle wildcard\n                FileSet fs = new FileSet();\n                File dir = file.getParentFile();\n                fs.setDir(dir);\n                fs.setIncludes(file.getName());\n                for (String included : fs.getDirectoryScanner(new Project()).getIncludedFiles()) {\n                    paths.add(new File(dir, included));\n                }\n            } else {\n                if (!file.exists())\n                    throw new IOException(\"No such file: \" + file);\n                paths.add(file);\n            }\n        }\n    }\n\n    /**\n     * Explodes the plugin into a directory, if necessary.\n     */\n    private static void explode(File archive, File destDir) throws IOException {\n        Util.createDirectories(Util.fileToPath(destDir));\n\n        // timestamp check\n        File explodeTime = new File(destDir, \".timestamp2\");\n        if (explodeTime.exists() && explodeTime.lastModified() == archive.lastModified())\n            return; // no need to expand\n\n        // delete the contents so that old files won't interfere with new files\n        Util.deleteRecursive(destDir);","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/core/src/main/java/hudson/ClassicPluginStrategy.java#L441-L477","documentation":"Thrown by parseClassPath while reading the Class-Path attribute from a plugin archive's JAR manifest. Jenkins resolves each entry relative to the archive parent; entries without a wildcard must exist on disk, otherwise loading aborts with this IOException. This mirrors the JAR Class-Path spec where referenced jars must sit beside the referencing jar.","triggerScenarios":"A plugin's MANIFEST.MF contains a Class-Path entry (or a custom attribute parsed via parseClassPath) whose non-wildcard path does not resolve to an existing file; the referenced file was deleted, never packaged, or the path is absolute and points off-host.","commonSituations":"Hand-edited manifest with a wrong relative path; build repackaged the plugin and dropped a sibling jar; plugin moved out of its expected directory so sibling libs are gone; absolute Class-Path entry pointing to a path that only exists on the build machine.","solutions":["Inspect the plugin archive's MANIFEST.MF Class-Path attribute and check each referenced path exists relative to the archive.","Rebuild the plugin with the build tool so the manifest Class-Path is generated correctly.","If a referenced jar is genuinely optional, use a wildcard entry (name contains *) instead of a literal path.","Reinstall the plugin from a known-good source so all sibling files are present."],"exampleFix":"// Manifest entry referencing a missing sibling\n// before: Class-Path: libs/missing.jar\n// after:  Class-Path: libs/present.jar   (ensure the file ships beside the plugin)","handlingStrategy":"validation","validationCode":"Manifest m = new JarFile(archive).getManifest();\nString cp = m.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);\nif (cp != null) {\n    for (String entry : cp.split(\" \")) {\n        File resolved = new File(archive.getParentFile(), entry);\n        if (!resolved.getName().contains(\"*\") && !resolved.exists()) {\n            throw new IllegalStateException(\"Missing Class-Path entry: \" + resolved);\n        }\n    }\n}","typeGuard":"null","tryCatchPattern":"try {\n    strategy.load(wrapper);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"No such file:\")) { /* log and skip the broken manifest entry */ }\n    else throw e;\n}","preventionTips":["Let the build tool generate the Class-Path manifest rather than hand-editing it.","Keep sibling libraries next to the referencing jar in the plugin layout.","Use wildcard Class-Path entries for optional companions."],"tags":["plugin-loading","manifest","classpath"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}