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

  1. Add the correct platform-specific native artifact (matching os classifier from PlatformDetector) to the build dependencies.
  2. Confirm the jar on the classpath actually contains the resource path printed in the error (jar tf | grep native/<classifier>).
  3. Check build/shade configuration isn't filtering or excluding 'native/' resources.
  4. 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

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


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)