github/copilot-sdk · error

Failed to write a frame to the in-process runtime…

Error message

Failed to write a frame to the in-process runtime connection.

What it means

The native connectionWrite call returned false, meaning the FFI layer could not deliver the frame buffer to the in-process runtime. Unlike error 80 the connection is nominally open, but the underlying write failed — typically because the runtime process/pipe is dead or backpressured beyond recovery. Thrown from writeFrame during the constructor's handshake write.

Solutions

  1. Reinstall the SDK so the correct platform runtime.node is present (see runtime bundle validation errors).
  2. Check the runtime process logs/stderr for a crash right before the write failure.
  3. Retry session creation — a transient runtime startup failure can produce a one-off write failure.
  4. Confirm the runtime bundle version matches the SDK version (mixed installs cause protocol/ABI mismatch).

Example fix

// before
const { runtimePath } = ensureRuntimeBundle({});
const host = new FfiRuntimeHost(loadLib(runtimePath)); // runtime node from an old install

// after
// reinstall @github/copilot-sdk and its platform package so versions match
npm install @github/copilot-sdk
Defensive patterns

Strategy: retry

Validate before calling

if (!existsSync(runtimePath)) throw new Error('runtime binary missing before connect');

Try / catch

try {
  host = new FfiRuntimeHost(lib);
} catch (e) {
  if (e.message.includes('Failed to write a frame')) {
    // transient native failure: rebuild lib+host with backoff
    await sleep(RETRY_MS);
    host = createHost();
  } else throw e;
}

Prevention

When it happens

Trigger: this.lib.connectionWrite(connectionId, frame, length) returns false for the initial handshake frame: the native runtime died at startup, the connection id became invalid, or the native buffer write failed.

Common situations: Corrupt or mismatched runtime.node binary, runtime crash immediately after launch, OOM-killed runtime process, platform-native binary version mismatch with the SDK.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/ee690c7b94d9cade. Report an issue: GitHub.

Appendix: source

Thrown at nodejs/src/ffiRuntimeHost.ts:248

            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.");
        }
    }

    /**
     * Native outbound (server→client) callback. koffi delivers it on the JS event loop
     * via a threadsafe function, so the frame is decoded and written straight to
     * {@link receiveStream}. The native pointer is only valid for this call, so the
     * bytes are copied out before returning.
     */
    private feedInbound(bytesPtr: unknown, bytesLen: number | bigint): void {
        // An exception thrown across the native→JS (Node-API) boundary cannot propagate
        // and would surface only as a DEP0168 "uncaught Node-API callback exception"
        // warning, so catch and log it here instead of letting it escape.
        try {
            // A native outbound callback can still be delivered on the event loop after
            // dispose() has ended receiveStream; writing then would throw
            // ERR_STREAM_WRITE_AFTER_END. Drop late frames instead — the connection is
            // gone and nothing is reading them.

View on GitHub (pinned to cd8cf15dc3)