{"record":{"id":"285ea51b23c4ab1c","repo":"github/copilot-sdk","slug":"runtime-asset-not-found-on-classpath","errorCode":null,"errorMessage":"Runtime asset not found on classpath: ","messagePattern":"Runtime asset not found on classpath: ","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java","lineNumber":474,"sourceCode":"                    throw new IOException(\"Invalid runtime asset inventory entry: \" + line);\n                }\n                boolean executable = (Integer.parseInt(fields[0], 8) & 0111) != 0;\n                Path relative = Path.of(fields[1]).normalize();\n                if (relative.isAbsolute() || relative.startsWith(\"..\")) {\n                    throw new IOException(\"Unsafe runtime asset inventory path: \" + fields[1]);\n                }\n                Path cached = cacheDir.resolve(relative).normalize();\n                if (!cached.startsWith(cacheDir)) {\n                    throw new IOException(\"Runtime asset escapes cache directory: \" + fields[1]);\n                }\n                if (isValidCachedFile(cached) && (!executable || isWindows() || Files.isExecutable(cached))) {\n                    continue;\n                }\n\n                String resourcePath = \"native/\" + classifier + \"/\" + fields[1];\n                URL resource = loader.getResource(resourcePath);\n                if (resource == null) {\n                    throw new FileNotFoundException(\"Runtime asset not found on classpath: \" + resourcePath);\n                }\n                Files.createDirectories(cached.getParent());\n                Path temp = Files.createTempFile(cached.getParent(), \"runtime-asset-tmp-\", \"\");\n                try {\n                    copyResourceToTemp(resource, resourcePath, temp);\n                    if (executable) {\n                        makeExecutable(temp);\n                    }\n                    publisher.publish(temp, cached);\n                } finally {\n                    tryDelete(temp);\n                }\n            }\n        } catch (NumberFormatException ex) {\n            throw new IOException(\"Invalid runtime asset mode in \" + inventoryResourcePath, ex);\n        }\n    }\n","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java#L456-L492","documentation":"Each runtime asset listed in the inventory must exist as a classpath resource under 'native/<classifier>/<path>'. When ClassLoader.getResource returns null for that resource path, the loader throws FileNotFoundException. This means the native artifact jar for this platform is missing from the classpath or the inventory lists a file that isn't bundled.","triggerScenarios":"extractRuntimeAssetsToCache (via extractRuntimeToCache) looks up 'native/<classifier>/<file>' and the resource is absent — e.g. the platform-specific native jar was excluded from the build, the classifier (os/arch/libc) is wrong, or the jar is partially published.","commonSituations":"Maven/Gradle build excluding 'native-*' classifier artifacts; running on an OS/arch combination whose native artifact isn't a dependency (e.g. linux-arm64 jar missing); shading/relocation breaking resource paths; thin WAR/fat-jar packaging dropping native resources.","solutions":["Add the correct platform-specific native artifact (matching os classifier from PlatformDetector) to the build dependencies.","Confirm the jar on the classpath actually contains the resource path printed in the error (jar tf | grep native/<classifier>).","Check build/shade configuration isn't filtering or excluding 'native/' resources.","Verify PlatformDetector's classifier matches the artifact you bundled (win32/linux × x64/arm64 × libc)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Java: check the native artifact is on the classpath before loading\nString classifier = \"linux-x64\"; // from PlatformDetector\nboolean present = NativeRuntimeLoader.class.getClassLoader()\n    .getResource(\"native/\" + classifier + \"/runtime.node\") != null;\nif (!present) throw new IllegalStateException(\"Add the native artifact for \" + classifier + \" to the classpath\");","typeGuard":null,"tryCatchPattern":"try { loader.loadRuntime(); } catch (FileNotFoundException e) { if (e.getMessage().startsWith(\"Runtime asset not found on classpath\")) { // add missing platform artifact dependency or fail fast with clear instructions } else throw e; }","preventionTips":["Declare the platform-specific native artifact for every target OS/arch in your build","After packaging, assert the jar contains native/<classifier> resources in CI","Beware shade/exclude rules filtering out native/** resources"],"tags":["classpath","missing-resource","java","native-assets"],"backgroundTag":"resource-not-found","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}