github/copilot-sdk · error · FileNotFoundException
Runtime asset not found on classpath:
Error message
Runtime asset not found on classpath:
What it means
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.
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).
Defensive patterns
Strategy: validation
Validate before calling
// Java: check the native artifact is on the classpath before loading
String classifier = "linux-x64"; // from PlatformDetector
boolean present = NativeRuntimeLoader.class.getClassLoader()
.getResource("native/" + classifier + "/runtime.node") != null;
if (!present) throw new IllegalStateException("Add the native artifact for " + classifier + " to the classpath"); Try / catch
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; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Unsafe runtime asset inventory path:
- Published Copilot CLI is not a non-empty executable file:
- Classpath resource is empty:
- Generated class + metaClassName + not found. Ensure the…
- Unknown WorkspaceDiffFileChangeType value
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/285ea51b23c4ab1c.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java:474
throw new IOException("Invalid runtime asset inventory entry: " + line);
}
boolean executable = (Integer.parseInt(fields[0], 8) & 0111) != 0;
Path relative = Path.of(fields[1]).normalize();
if (relative.isAbsolute() || relative.startsWith("..")) {
throw new IOException("Unsafe runtime asset inventory path: " + fields[1]);
}
Path cached = cacheDir.resolve(relative).normalize();
if (!cached.startsWith(cacheDir)) {
throw new IOException("Runtime asset escapes cache directory: " + fields[1]);
}
if (isValidCachedFile(cached) && (!executable || isWindows() || Files.isExecutable(cached))) {
continue;
}
String resourcePath = "native/" + classifier + "/" + fields[1];
URL resource = loader.getResource(resourcePath);
if (resource == null) {
throw new FileNotFoundException("Runtime asset not found on classpath: " + resourcePath);
}
Files.createDirectories(cached.getParent());
Path temp = Files.createTempFile(cached.getParent(), "runtime-asset-tmp-", "");
try {
copyResourceToTemp(resource, resourcePath, temp);
if (executable) {
makeExecutable(temp);
}
publisher.publish(temp, cached);
} finally {
tryDelete(temp);
}
}
} catch (NumberFormatException ex) {
throw new IOException("Invalid runtime asset mode in " + inventoryResourcePath, ex);
}
}
View on GitHub (pinned to cd8cf15dc3)