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

  1. 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.
  2. Verify the JAR contains native/<classifier>/copilot-runtime: jar tf copilot-sdk-native-*.jar | grep copilot-runtime.
  3. Check build/shading config (maven-shade-plugin filters, spring-boot layers) isn't excluding native/ resources.
  4. 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

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


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)