github/copilot-sdk · error · IllegalStateException
Filesystem does not support atomic moves; cannot safely…
Error message
Filesystem does not support atomic moves; cannot safely publish runtime to
What it means
NativeRuntimeLoader's DEFAULT_PUBLISHER publishes the extracted runtime to its cache location using Files.move with ATOMIC_MOVE. If the filesystem does not support atomic moves (e.g. some network mounts, overlay quirks), publishing cannot be done safely and the loader throws rather than risk a partially visible library.
Solutions
- Move the runtime cache directory to a local filesystem path (e.g. /tmp or a local disk).
- Provide a custom AtomicPublisher that handles non-atomic moves with a lock/rename-into-place scheme.
- Avoid sharing the cache directory across devices; keep temp file and target in the same volume.
- Update the loader to fall back to non-atomic move if your use case tolerates it.
Example fix
// before cacheDir = "/mnt/nfs/shared/copilot-runtime"; // after cacheDir = "/var/tmp/copilot-runtime"; // local filesystem supporting ATOMIC_MOVE
Defensive patterns
Strategy: fallback
Validate before calling
try { Path t = Files.createTempFile(cacheDir, "t", ".tmp"); Files.move(t, t.resolveSibling("m"), StandardCopyOption.ATOMIC_MOVE); } catch (AtomicMoveNotSupportedException e) { /* switch cacheDir to local fs */ } Try / catch
try { lib = NativeRuntimeLoader.ensureRuntime(); } catch (IllegalStateException ex) { if (ex.getMessage().contains("atomic moves")) { lib = NativeRuntimeLoader.ensureRuntime(localCacheDir()); } else throw ex; } Prevention
- Place runtime cache on local disk, not NFS/SMB mounts
- Keep temp and target files in the same filesystem/volume
- Test runtime extraction on the actual container/volume setup in CI
When it happens
Trigger: Cache directory resides on a filesystem rejecting ATOMIC_MOVE: NFS/SMB/CIFS mounts, some container volume mounts, or cross-device move attempts.
Common situations: Building/running in Docker with the Maven/Gradle cache on a network volume; CI agents with workspaces on NFS; pointing the runtime cache at a mounted share.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- copilot_runtime_host_start failed (library '').
- copilot_runtime_connection_open failed.
- Failed to load native library from ''
- An in-process FFI runtime library is already loaded from…
- Runtime asset escapes cache directory:
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/8b7d557fd388a1ca.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java:85
* fully-written temporary file in the same directory as
* {@code cached}
* @param cached
* intended final location
* @throws IOException
* if the move fails
*/
void publish(Path temp, Path cached) throws IOException;
}
/**
* Production publisher: {@link Files#move} with
* {@link StandardCopyOption#ATOMIC_MOVE}.
*/
static final AtomicPublisher DEFAULT_PUBLISHER = (temp, cached) -> {
try {
Files.move(temp, cached, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
} catch (AtomicMoveNotSupportedException ex) {
throw new IllegalStateException("Filesystem does not support atomic moves; cannot safely publish "
+ RUNTIME_FILENAME + " to " + cached, ex);
} catch (FileAlreadyExistsException | AccessDeniedException ex) {
// Windows can report AccessDeniedException instead of
// FileAlreadyExistsException when another publisher wins the race.
try {
if (isValidCachedFile(cached)) {
return;
}
} catch (IOException ignored) {
// fall through to the error below
}
throw new IllegalStateException(
"Concurrent extraction race: target already exists but is not a valid file: " + cached, ex);
}
};
private NativeRuntimeLoader() {
}View on GitHub (pinned to cd8cf15dc3)