github/copilot-sdk · error · IllegalStateException
Classpath resource is empty:
Error message
Classpath resource is empty:
What it means
copyResourceToTemp copies a classpath resource to a temp file and counts bytes written; a zero-byte result means the resource opened successfully but contained no data. The loader throws IllegalStateException because an empty native binary/asset is never valid — publishing it would cache a broken executable. This indicates the bundled artifact resource is empty or the stream was truncated.
Solutions
- Verify the resource inside the jar is non-empty (unzip -l / jar tf and extract to compare sizes); replace the artifact if empty.
- Disable Maven resource filtering for binary/native resources (<filtering>false</filtering> on the native directory).
- Re-download/rebuild the artifact and confirm checksums match the official release.
- Clear the local cache dir so partial/truncated prior extractions aren't reused.
Example fix
// before (pom.xml) <resource><directory>src/main/resources</directory><filtering>true</filtering></resource> // after <resource><directory>src/main/resources</directory><filtering>false</filtering><excludes><exclude>native/**</exclude></excludes></resource>
Defensive patterns
Strategy: validation
Validate before calling
// Java: verify classpath resources are non-empty before extraction
String resourcePath = "native/linux-x64/runtime.node";
try (InputStream in = loader.getResourceAsStream(resourcePath)) {
if (in == null || in.read() == -1) throw new IllegalStateException("Empty/missing classpath resource: " + resourcePath);
} Try / catch
try { loader.loadRuntime(); } catch (IllegalStateException e) { if (e.getMessage().startsWith("Classpath resource is empty")) { // artifact jar is corrupt: rebuild/re-download and verify checksum } else throw e; } Prevention
- Never enable Maven resource filtering on binary/native resources
- Verify artifact checksums after download or CI publish
- Reject 0-byte files when committing native binaries
- Clear the local cache after replacing artifact versions
When it happens
Trigger: resource.openStream() yields 0 bytes for 'native/<classifier>/<file>' or the CLI resource during any extraction path (resolveRuntimeWrapper, extractRuntimeToCache, extractRuntimeAssetsToCache, extractCliToCache).
Common situations: A 0-byte file committed into the artifact jar; a broken release build that packaged empty natives; download corruption when the jar was fetched; a stub/placeholder resource left by misconfigured resource filtering (maven filtering corrupting binaries).
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Invalid runtime asset inventory entry:
- Runtime asset not found on classpath:
- Generated class + metaClassName + not found. Ensure the…
- Unknown WorkspaceDiffFileChangeType value
- Unknown WorkspaceDiffMode value
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/b5457e926292a59f.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java:585
if (isWindows()) {
return;
}
final boolean executableSet;
try {
executableSet = path.toFile().setExecutable(true, false);
} catch (SecurityException ex) {
throw new IOException("Failed to make Copilot CLI executable: " + path, ex);
}
if (!executableSet || !Files.isExecutable(path)) {
throw new IOException("Failed to make Copilot CLI executable: " + path);
}
}
private static void copyResourceToTemp(URL resource, String resourcePath, Path temp) throws IOException {
try (InputStream in = resource.openStream()) {
long bytesWritten = Files.copy(in, temp, StandardCopyOption.REPLACE_EXISTING);
if (bytesWritten == 0) {
throw new IllegalStateException("Classpath resource is empty: " + resourcePath);
}
}
// Flush OS buffers to durable storage before the atomic rename.
try (FileChannel channel = FileChannel.open(temp, StandardOpenOption.WRITE)) {
channel.force(true);
}
}
/**
* Finds the Copilot CLI executable on the {@code PATH}.
*
* @return the absolute CLI path, or {@code null} if none was found
*/
public static String findRuntimeOnPath() {
String pathValue = System.getenv("PATH");
if (pathValue == null || pathValue.isBlank()) {
return null;
}View on GitHub (pinned to cd8cf15dc3)