github/copilot-sdk · error · InvalidOperationException
FFI runtime library not found. Looked for
Error message
FFI runtime library not found. Looked for '{flatLibraryPath}', '{adjacentPrebuildPath}', and '{prebuildsLibraryPath}'. What it means
CopilotClient needs the native FFI runtime library (`runtime.node`) to host the CLI in-process. It probes three well-known locations — a flat path, an adjacent `prebuilds` path, and the napi-rs `prebuilds/<platform>-<arch>/` layout — and throws InvalidOperationException when none exists. This means the native runtime binary was never installed or is laid out for a different platform/arch.
Solutions
- Reinstall/upgrade the Copilot SDK package so the native FFI runtime (runtime.node) is restored into the output directory or prebuilds folder.
- Verify the file actually exists at one of the three printed paths; manually copy runtime.node into prebuilds/<platform>-<arch>/ if it was stripped.
- Ensure your publish/CI pipeline does not exclude native assets (check csproj Content/None Include rules and dotnet publish trimming settings).
- Confirm the host platform/arch matches an available napi-rs prebuild; fall back to stdio/CLI hosting if FFI hosting is unavailable.
Example fix
// before: assumes FFI runtime is present
copilot = new CopilotClient(); // InvalidOperationException at startup
// after: ensure native asset is copied, or fall back to stdio
if (!File.Exists(Path.Combine(AppContext.BaseDirectory, "prebuilds", "linux-x64", "runtime.node")))
{
// use a runtime mode that spawns the CLI process instead of FFI hosting
copilot = new CopilotClient(useStdio: true);
} Defensive patterns
Strategy: fallback
Validate before calling
var prebuilds = Path.Combine(AppContext.BaseDirectory, "prebuilds", "linux-x64", "runtime.node");
if (!File.Exists(prebuilds))
throw new InvalidOperationException("FFI runtime missing; use stdio mode"); Try / catch
try { client = new CopilotClient(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("FFI runtime library not found"))
{ client = new CopilotClient(useStdio: true); } Prevention
- Verify runtime.node exists in the output dir after restore/publish in CI
- Do not strip native assets with publish trimming rules
- Pin the SDK package version so prebuilds match your platform
When it happens
Trigger: Starting the client with FFI runtime hosting when none of flatLibraryPath, adjacentPrebuildPath, or prebuildsLibraryPath exist on disk (GetFFILibraryPath-style resolution returned no match).
Common situations: NuGet package installed without the native runtime asset included; publishing/trimming a .NET app that drops the runtime.node content file; downloading a prebuilt binary for the wrong OS/arch; running on a platform napi-rs does not ship prebuilds for (e.g. linux-musl variants).
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- In-process FFI runtime library not found at
- copilot_runtime_host_start failed
- copilot_runtime_connection_open failed.
- Could not determine a napi-rs prebuilds folder for FFI…
- FFI runtime library not found at
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/5d9e75eeaff1a7d9.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/Client.cs:2573
var fullEntrypoint = Path.GetFullPath(cliPath);
var directory = Path.GetDirectoryName(fullEntrypoint)
?? throw new InvalidOperationException($"Could not determine directory for '{cliPath}'.");
var flatLibraryPath = Path.GetFullPath(
$"{directory}{Path.DirectorySeparatorChar}{FfiRuntimeHost.GetRuntimeLibraryFileName()}");
if (File.Exists(flatLibraryPath))
{
return flatLibraryPath;
}
var adjacentPrebuildPath = Path.Combine(directory, "runtime.node");
if (File.Exists(adjacentPrebuildPath))
{
return adjacentPrebuildPath;
}
var prebuildsLibraryPath = Path.Combine(
directory, "prebuilds", GetNapiPrebuildsFolderOrThrow(), "runtime.node");
return File.Exists(prebuildsLibraryPath)
? prebuildsLibraryPath
: throw new InvalidOperationException(
$"FFI runtime library not found. Looked for '{flatLibraryPath}', '{adjacentPrebuildPath}', and '{prebuildsLibraryPath}'.");
}
/// <summary>
/// Returns the napi-rs prebuilds folder name for the current host — the
/// <c><node-platform>-<arch></c> convention (e.g. <c>win32-x64</c>,
/// <c>darwin-arm64</c>, <c>linux-x64</c>) under which the runtime ships
/// <c>prebuilds/<folder>/runtime.node</c>. This differs from the .NET RID
/// (<c>win-x64</c>/<c>osx-x64</c>) for Windows and macOS.
/// </summary>
private static string? GetNapiPrebuildsFolder()
{
string platform;
if (OperatingSystem.IsWindows()) platform = "win32";
else if (OperatingSystem.IsLinux())
{
platform = RuntimeInformation.RuntimeIdentifier.StartsWith("linux-musl-", StringComparison.Ordinal)
? "linuxmusl"View on GitHub (pinned to cd8cf15dc3)