github/copilot-sdk · critical · InvalidOperationException
copilot_runtime_connection_open failed.
Error message
copilot_runtime_connection_open failed.
What it means
Thrown by FfiRuntimeHost.StartAsync when the native call copilot_runtime_connection_open returns a null handle (0), meaning the in-process FFI runtime could not open a connection for this server. The host cleans up (disposes callbacks, shuts down the native host) and surfaces the failure as InvalidOperationException so the async start task fails visibly.
Solutions
- Verify the FFI runtime library matches the version of the managed dotnet package (reinstall/restore to get a matched pair).
- Check earlier log lines for a more specific native-side failure during connection open.
- Dispose the FfiRuntimeHost fully and create a fresh instance instead of restarting a failed one.
- Test loading the runtime library in isolation (PrepareNativeLibrary/bind path) to confirm exports resolve.
- Capture native crash logs / run with debug logging enabled to see the runtime's own error before it returns 0.
Example fix
// before var host = Create(staleLibraryPath); await host.StartAsync(token); // connection open fails // after var host = Create(matchedRuntimeLibraryPath); // version-matched native lib await host.StartAsync(token);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!File.Exists(runtimeLibraryPath)) throw new FileNotFoundException(runtimeLibraryPath); // plus version check of native lib vs package
Type guard
bool IsRuntimeUsable(FfiRuntimeHost? h) => h is not null && !h.IsDisposed;
Try / catch
try { await host.StartAsync(ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("connection_open failed")) {
logger.LogError(ex, "Runtime connection open failed; recreating host");
host.Dispose(); host = FfiRuntimeHost.Create(resolvedLibraryPath);
} Prevention
- Keep native runtime and managed package versions locked together
- Enable debug logging around StartAsync to capture native-side causes
- Avoid reusing a host instance after a failed start
- Verify the native binary loads before starting servers
When it happens
Trigger: Calling StartAsync when the native runtime's connection-open entry point fails — e.g. the runtime library was loaded but is incompatible, corrupted, or its internal state is broken from a prior failed start/shutdown cycle.
Common situations: Mismatched native runtime binary vs managed wrapper version; a corrupted or partially installed runtime library; starting a second server after a prior native failure left the host in a bad state.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- copilot_runtime_connection_open failed.
- An in-process FFI runtime library is already loaded from
- FFI runtime library not found at
- copilot_runtime_host_start failed
- The in-process runtime connection is closed.
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/24f9d01913bff3e2.
Report an issue: GitHub.
Appendix: source
Thrown at dotnet/src/FfiRuntimeHost.cs:125
await Task.Run(() =>
{
var argvJson = BuildArgvJson(_cliEntrypoint, _args);
var envJson = BuildEnvJson(_environment);
_serverId = NativeHostStart(argvJson, envJson);
if (_serverId == 0)
{
throw new InvalidOperationException(
$"copilot_runtime_host_start failed (library '{_libraryPath}').");
}
_connectionId = NativeOpenConnection(_serverId);
if (_connectionId == 0)
{
DisposeNativeCallback();
NativeHostShutdown(_serverId);
_serverId = 0;
throw new InvalidOperationException("copilot_runtime_connection_open failed.");
}
_sendStream = new CallbackSendStream(SendFrame);
}, cancellationToken).ConfigureAwait(false);
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug(
"FfiRuntimeHost started. Library={Library}, ServerId={ServerId}, ConnectionId={ConnectionId}",
_libraryPath, _serverId, _connectionId);
}
}
private static byte[] BuildArgvJson(string? cliEntrypoint, IReadOnlyList<string> args)
{
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream))
{View on GitHub (pinned to cd8cf15dc3)