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

  1. Verify the FFI runtime library matches the version of the managed dotnet package (reinstall/restore to get a matched pair).
  2. Check earlier log lines for a more specific native-side failure during connection open.
  3. Dispose the FfiRuntimeHost fully and create a fresh instance instead of restarting a failed one.
  4. Test loading the runtime library in isolation (PrepareNativeLibrary/bind path) to confirm exports resolve.
  5. 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

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


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)