github/copilot-sdk · error · RuntimeError
WebSocket forwarding requires the 'websockets' package…
Error message
WebSocket forwarding requires the 'websockets' package. Install it or override open_websocket().
What it means
The WebSocket forwarding path needs the third-party 'websockets' package to establish the upstream connection. It is an optional dependency; when the import fails, open() raises RuntimeError telling the user to install it or override open_websocket() with a custom implementation.
Solutions
- Install the optional dependency: pip install 'websockets' (or the package's websocket extra)
- Subclass and override open_websocket() to supply your own upstream connection implementation
- Pin the dependency in your requirements/Dockerfile so deployment images always include it
- Check import websockets in a startup smoke test to fail at boot, not per-request
Example fix
// before handler = CopilotWebSocketRequestHandler(context) await handler.open() # RuntimeError: websockets missing // after # pip install websockets await handler.open()
Defensive patterns
Strategy: fallback
Validate before calling
try:
import websockets
HAS_WEBSOCKETS = True
except ImportError:
HAS_WEBSOCKETS = False Type guard
def websockets_available() -> bool:
try:
import websockets # noqa: F401
return True
except ImportError:
return False Try / catch
try:
await handler.open()
except RuntimeError as e:
if "websockets" in str(e):
handler = CustomHandlerWithOwnWebSocket(context)
await handler.open()
else:
raise Prevention
- Install the websocket extra: pip install 'websockets'
- Pin 'websockets' in requirements/Dockerfile
- Override open_websocket() when using a custom websocket stack
- Run an import smoke test at application startup
When it happens
Trigger: Calling open() (directly or via the request lifecycle) on CopilotWebSocketRequestHandler without overriding open_websocket(), in an environment where 'websockets' is not installed.
Common situations: Minimal/production installs that omitted the websocket extra, Docker images with only core deps, or environments that use a different websocket library.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- WebSocket response bridge is not attached
- Copilot request was cancelled by the runtime.
- Copilot request response used after RPC connection closed.
- WebSocket response bridge is not attached.
- WebSocket response bridge is not attached
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/5b9c00228c7e75fb.
Report an issue: GitHub.
Appendix: source
Thrown at python/copilot/copilot_request_handler.py:195
"""Default pass-through WebSocket handler backed by the ``websockets`` library."""
def __init__(self, context: CopilotRequestContext) -> None:
super().__init__(context)
self._upstream: Any | None = None
self._receive_task: asyncio.Task[None] | None = None
async def send_request_message(self, data: str | bytes) -> None:
if self._upstream is None:
return
await self._upstream.send(data)
async def open(self) -> None:
if self._upstream is not None:
return
try:
import websockets
except ImportError as exc: # pragma: no cover - optional dependency
raise RuntimeError(
"WebSocket forwarding requires the 'websockets' package. "
"Install it or override open_websocket()."
) from exc
headers = [
(name, value)
for name, values in self.context.headers.items()
if name.lower() not in _FORBIDDEN_REQUEST_HEADERS
for value in (values or [])
]
self._upstream = await websockets.connect(self.context.url, additional_headers=headers)
self._receive_task = asyncio.create_task(self._receive_loop())
async def _receive_loop(self) -> None:
try:
async for message in self._upstream: # type: ignore[union-attr]
await self.send_response_message(message)
await self.close(CopilotWebSocketCloseStatus.normal_closure())View on GitHub (pinned to cd8cf15dc3)