github/copilot-sdk · error
An in-process FFI runtime library is already loaded from
Error message
An in-process FFI runtime library is already loaded from '${loadedLibraryPath}'; loading a different library from '${libraryPath}' in the same process is not supported. What it means
The FFI runtime host loads a native cdylib once per process (module-level loadedLibrary state). If loadLibrary is asked for a path that differs from the already-loaded library path, it throws because a second copy of the same C ABI in one process is unsupported (duplicated global state, callback registration conflicts).
Solutions
- Use the same library path for all FfiRuntimeHost instances in a process, or reuse the existing host instance.
- Restart the process when you need to load a different library build/version.
- Centralize host creation (singleton) so only one path is ever requested.
- Fix test/watch tooling to spawn a fresh process per library variant.
Example fix
// before
new FfiRuntimeHost('/lib/runtime-debug.so', ...);
new FfiRuntimeHost('/lib/runtime-release.so', ...); // throws
// after
new FfiRuntimeHost('/lib/runtime-release.so', ...); // consistent path (or reuse host) Defensive patterns
Strategy: try-catch
Validate before calling
const LIB_PATH = '/abs/path/libruntime.so'; // single shared constant // only ever construct with LIB_PATH
Try / catch
let host;
try {
host = new FfiRuntimeHost(libPath, ...);
} catch (e) {
if (String(e.message).includes('already loaded from')) {
host = getExistingHost(); // reuse the host bound to the loaded library
} else throw e;
} Prevention
- Centralize library path in one constant/module
- Use a singleton host accessor instead of constructing repeatedly
- Restart the process to switch library builds
- Configure test runners to use one library variant per process
When it happens
Trigger: Constructing a second FfiRuntimeHost in the same process with a different libraryPath than the first (e.g. pointing at another build output, version, or architecture variant of the cdylib).
Common situations: Test suites that switch between debug and release builds of the native library; upgrading library paths mid-process after a rebuild; multiple SDK versions of the runtime coexisting; watch-mode rebuilds changing the library file path while the process is alive.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- FFI runtime library not found at
- copilot_runtime_host_start failed
- copilot_runtime_connection_open failed.
- The in-process runtime connection is closed.
- FfiRuntimeHost is already closed.
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/c8d861dc9ef84eac.
Report an issue: GitHub.
Appendix: source
Thrown at nodejs/src/ffiRuntimeHost.ts:52
hostStart: KoffiFunction;
hostShutdown: KoffiFunction;
connectionOpen: KoffiFunction;
connectionWrite: KoffiFunction;
connectionClose: KoffiFunction;
outboundCallbackType: KoffiType;
}
let loadedLibraryPath: string | undefined;
let loadedLibrary: FfiLibrary | undefined;
/**
* Loads the cdylib once per process and binds the C ABI exports. Loading a
* different library path in the same process is unsupported.
*/
function loadLibrary(libraryPath: string): FfiLibrary {
if (loadedLibrary) {
if (loadedLibraryPath !== libraryPath) {
throw new Error(
`An in-process FFI runtime library is already loaded from '${loadedLibraryPath}'; ` +
`loading a different library from '${libraryPath}' in the same process is not supported.`
);
}
return loadedLibrary;
}
const lib = koffi.load(libraryPath);
const outboundCallbackType = koffi.pointer(
koffi.proto(
`void ${SYMBOL_PREFIX}outbound(void *userData, uint8 *bytesPtr, size_t bytesLen)`
)
);
loadedLibrary = {
hostStart: lib.func(`${SYMBOL_PREFIX}host_start`, "uint32", [
"uint8*",
"size_t",View on GitHub (pinned to cd8cf15dc3)