github/copilot-sdk · error

Copilot request response used after RPC connection closed.

Error message

Copilot request response used after RPC connection closed.

What it means

Responses are delivered to the runtime via an RPC connection obtained through #rpc(). If that connection has closed (or was never available), the handler cannot forward httpResponseStart/Chunk calls. #rpc() throws this error whenever the server RPC accessor returns nothing.

Solutions

  1. Check connection state before starting response emission and skip/abort the response if the RPC connection is down.
  2. Keep handler processing short so the response is emitted within the connection's lifetime.
  3. Wrap the whole emit sequence in try/catch and treat this as an unrecoverable transport failure — log and return.
  4. Investigate why the RPC connection closed (runtime exit, timeout, network) if this occurs routinely.
  5. Enable reconnect/keepalive at the client/runtime layer if supported by your setup.

Example fix

// before
await longCompute();
await handler.startResponse({ status: 200 }); // may throw if RPC closed
// after
if (!handler.rpcConnected) return; // skip emission when transport is gone
await longCompute();
await handler.startResponse({ status: 200 });
Defensive patterns

Strategy: try-catch

Validate before calling

function isRpcClosed(e: unknown): boolean {
  return e instanceof Error && e.message.includes('used after RPC connection closed');
}
// check before emitting
if (typeof handler.rpcConnected === 'boolean' && !handler.rpcConnected) return;

Try / catch

try {
  await handler.startResponse({ status: 200 });
  await handler.writeResponse(body);
  await handler.endResponse();
} catch (e) {
  if (isRpcClosed(e)) { log.warn('response dropped: RPC connection closed'); return; }
  throw e;
}

Prevention

When it happens

Trigger: The WebSocket/RPC connection to the Copilot runtime closes while the handler is still emitting the response — calling startResponse, writeResponse, endResponse, or errorResponse afterwards.

Common situations: Long-running handlers that outlive the connection (runtime restart, network drop, client process exit); slow work followed by response emission after the session ended.

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

Appendix: source

Thrown at nodejs/src/copilotRequestHandler.ts:640

    }

    async errorResponse(error: { message: string; code?: string }): Promise<void> {
        if (this.#finished) {
            return;
        }
        this.#finished = true;
        await this.#rpc().llmInference.httpResponseChunk({
            requestId: this.requestId,
            data: "",
            end: true,
            error: { message: error.message, code: error.code },
        });
    }

    #rpc(): ServerRpc {
        const r = this.#getServerRpc();
        if (!r) {
            throw new Error("Copilot request response used after RPC connection closed.");
        }
        return r;
    }
}

const FORBIDDEN_REQUEST_HEADERS = new Set([
    "host",
    "connection",
    "content-length",
    "transfer-encoding",
    "keep-alive",
    "upgrade",
    "proxy-connection",
    "te",
    "trailer",
]);

async function buildFetchRequest(exchange: CopilotRequestExchange): Promise<Request> {

View on GitHub (pinned to cd8cf15dc3)