github/copilot-sdk · critical

copilot_runtime_connection_open failed.

Error message

copilot_runtime_connection_open failed.

What it means

start() opens the client connection via copilot_runtime_connection_open after the host server starts. If the returned connectionId is falsy, it throws this error after cleaning up: it unregisters the outbound callback, shuts down the server, and resets serverId, leaving no partially initialized state.

Solutions

  1. Rebuild/align the native library version with the JS SDK so the connection ABI matches.
  2. Validate the environment, CLI entrypoint, and args passed to create; fix invalid host configuration.
  3. Check native-side logs for the underlying connection_open failure cause.
  4. Retry in a fresh process after cleanup to rule out residual native state.

Example fix

// before
const host = FfiRuntimeHost.create(libPath, undefined, env, args);
await host.start(); // throws: connection_open failed
// after
const host = FfiRuntimeHost.create(libPath, resolve('./cli-entrypoint'), env, args);
await host.start(); // valid config lets connection_open succeed
Defensive patterns

Strategy: retry

Validate before calling

// validate config the host will use before start
if (!cliEntrypoint || !existsSync(resolve(cliEntrypoint))) throw new Error('Valid CLI entrypoint required for connection open');

Try / catch

try {
  await host.start();
} catch (e) {
  if (String(e.message).includes('copilot_runtime_connection_open failed')) {
    // start() already cleaned up server/callbacks; safe to retry with fixed config
    host = await recreateHostWithFixedConfig();
    await host.start();
  } else throw e;
}

Prevention

When it happens

Trigger: Calling start() when the native connection_open call fails — e.g. the host server started but could not open the in-process connection, native-side connection limits or configuration errors, or an ABI/version mismatch affecting the connection handshake.

Common situations: Mismatched native library version with different connection semantics; invalid host/CLI configuration that the connection setup rejects; resource exhaustion or native-side state preventing connection creation.

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/db3ff6124290b635. Report an issue: GitHub.

Appendix: source

Thrown at nodejs/src/ffiRuntimeHost.ts:232

            this.lib.outboundCallbackType
        );

        this.connectionId = this.lib.connectionOpen(
            this.serverId,
            this.outboundCallback,
            null,
            null,
            0,
            null,
            0,
            null,
            0
        );
        if (!this.connectionId) {
            this.unregisterCallback();
            this.lib.hostShutdown(this.serverId);
            this.serverId = 0;
            throw new Error("copilot_runtime_connection_open failed.");
        }

        // The in-process transport has no socket/pipe handle to keep the Node event loop
        // alive while the SDK is idle awaiting a server→client frame. koffi delivers the
        // outbound callback on the loop but does not reference it, so hold one referenced
        // timer for the lifetime of the connection.
        this.keepAliveTimer = setInterval(() => {}, KEEP_ALIVE_INTERVAL_MS);
    }

    private writeFrame(frame: Buffer): void {
        if (this.disposed || !this.connectionId) {
            throw new Error("The in-process runtime connection is closed.");
        }
        const ok = this.lib.connectionWrite(this.connectionId, frame, frame.length);
        if (!ok) {
            throw new Error("Failed to write a frame to the in-process runtime connection.");
        }
    }

View on GitHub (pinned to cd8cf15dc3)