github/copilot-sdk · error · FileNotFoundException
Runtime wrapper not found on classpath: — add the matching…
Error message
Runtime wrapper not found on classpath: — add the matching classifier JAR to the classpath
What it means
resolveRuntimeWrapper() could not find the classpath resource native/<classifier>/copilot-runtime (or copilot-runtime.exe on Windows). The runtime wrapper executable ships in a platform-specific classifier JAR; without it on the classpath the out-of-process runtime cannot be launched.
Solutions
- Add the Maven dependency for the classifier matching the running platform (e.g. <classifier>linux-x64</classifier> native artifact) at the same version as the SDK.
- Verify the JAR contains native/<classifier>/copilot-runtime: jar tf copilot-sdk-native-*.jar | grep copilot-runtime.
- Check build/shading config (maven-shade-plugin filters, spring-boot layers) isn't excluding native/ resources.
- Confirm PlatformDetector.detectClassifier() resolves to a platform you have a JAR for.
Example fix
// before (pom.xml): only SDK jar <dependency> <groupId>com.github.copilot</groupId> <artifactId>copilot-sdk</artifactId> <version>1.2.0</version> </dependency> // after: add matching native classifier JAR <dependency> <groupId>com.github.copilot</groupId> <artifactId>copilot-sdk-native</artifactId> <version>1.2.0</version> <classifier>linux-x64</classifier> </dependency>
Defensive patterns
Strategy: validation
Validate before calling
String classifier = detectClassifier(); // e.g. linux-x64
boolean wrapperPresent = getClass().getResourceAsStream("/native/" + classifier + "/copilot-runtime") != null;
if (!wrapperPresent) throw new IllegalStateException("Classifier JAR missing runtime wrapper for " + classifier);
Try / catch
try {
Path wrapper = NativeRuntimeLoader.resolveRuntimeWrapper();
} catch (FileNotFoundException e) {
// fail fast with actionable message pointing at the classifier dependency
throw new IllegalStateException("Add copilot-sdk-native classifier JAR to the classpath", e);
} Prevention
- Always add the native classifier JAR dependency at the same version as the SDK.
- Smoke-test in a clean container that resolution succeeds before deploying.
- Audit shade/packaging filters so native/** resources are never excluded.
- Pin SDK and native artifact versions together (BOM or common parent).
When it happens
Trigger: Calling NativeRuntimeLoader.resolveRuntimeWrapper() when the classifier JAR for the detected platform (e.g. copilot-sdk-native-linux-x64) is not a dependency, or an older classifier JAR predating the wrapper artifact.
Common situations: Adding the SDK but forgetting the native classifier dependency; running on an OS/arch with no published classifier JAR; a fat JAR/shading build that excluded native/<classifier>/ resources; upgrading the SDK without upgrading the classifier JAR (wrapper filename added later).
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
- Native runtime metadata not found on classpath: — add the…
- Native runtime not found on classpath: — add the matching…
- Copilot CLI executable not found at — the classifier JAR…
- Missing version resource: — ensure Maven resource…
- Blank or missing 'version' property in
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/a688372febc03172.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java:202
return resolveRuntimeWrapper(defaultCacheBase(), loader, classifier, version);
}
static Path resolveRuntimeWrapper(Path cacheBase, ClassLoader loader, String classifier, String version)
throws IOException {
Path runtimePath = extractRuntimeToCache(cacheBase, loader, classifier, version, DEFAULT_PUBLISHER, false);
Path cacheDir = runtimePath.getParent();
String wrapperName = classifier.startsWith("win32-")
? RUNTIME_WRAPPER_FILENAME_WINDOWS
: RUNTIME_WRAPPER_FILENAME;
Path cachedWrapper = cacheDir.resolve(wrapperName);
if (isValidCachedCli(cachedWrapper)) {
return cachedWrapper;
}
String resourcePath = "native/" + classifier + "/" + wrapperName;
URL resource = loader.getResource(resourcePath);
if (resource == null) {
throw new FileNotFoundException("Runtime wrapper not found on classpath: " + resourcePath
+ " — add the matching classifier JAR to the classpath");
}
Path temp = Files.createTempFile(cacheDir, "runtime-wrapper-tmp-", "");
try {
copyResourceToTemp(resource, resourcePath, temp);
makeExecutable(temp);
DEFAULT_PUBLISHER.publish(temp, cachedWrapper);
} finally {
tryDelete(temp);
}
if (!isValidCachedCli(cachedWrapper)) {
throw new IOException("Published runtime wrapper is not a non-empty executable file: " + cachedWrapper);
}
return cachedWrapper;
}
static Path resolveEntrypoint(String configuredCli, Path runtimePath) throws IOException {View on GitHub (pinned to cd8cf15dc3)