github/copilot-sdk · error · RuntimeError
Copilot request response start() called twice.
Error message
Copilot request response start() called twice.
What it means
start_response() is the state-machine entry point for a Copilot request's HTTP response and must be called exactly once before streaming body data. The library sets a `started` flag after the first call and raises this RuntimeError on any subsequent call, since a single HTTP response can only begin once per request_id. This guards against double-issuing the LlmInferenceHTTPResponseStart RPC to the runtime.
Solutions
- Check `response.started` before calling start_response(), or track whether your code already started the response.
- Ensure only one code path (either _finalize or _stream_response_to_exchange) is responsible for starting the response.
- If you need to send headers again for a different response, create a fresh response/request instead of reusing the finished one.
Example fix
// before
await response.start_response(200, "OK", headers)
await response.start_response(200, "OK", headers) # duplicate
// after
if not response.started:
await response.start_response(200, "OK", headers) Defensive patterns
Strategy: validation
Validate before calling
if response.started:
raise RuntimeError("response already started; skipping duplicate start_response") Type guard
def can_start(response) -> bool:
return not getattr(response, "started", False) and not getattr(response, "finished", False) Try / catch
try:
await response.start_response(status, status_text, headers)
except RuntimeError as e:
if "called twice" not in str(e):
raise Prevention
- Designate a single owner for calling start_response (one code path, not both _finalize and the streamer).
- Track response state locally and assert single-start in debug builds.
- Never reuse a response object across requests or retries.
When it happens
Trigger: Calling response.start_response() a second time on the same response object — e.g. calling it again after _finalize or after _stream_response_to_exchange has already invoked it, or wrapping start_response in retry logic that retries an already-successful call.
Common situations: Custom response pipelines that call start_response both explicitly and via a framework adapter; error-handling paths that try to start an error response after the success path already started it; accidental double-invocation when both _finalize and a streaming helper run.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Copilot request response already finished.
- Copilot request response write() called before start().
- Copilot request response write() called after end()/error().
- Copilot request was cancelled by the runtime.
- Request cancelled by runtime
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/34a983fd70e687eb.
Report an issue: GitHub.
Appendix: source
Thrown at python/copilot/copilot_request_handler.py:441
@property
def request_body(self) -> _BodyQueue:
return self._queue
def _require_rpc(self) -> ServerLlmInferenceApi:
rpc = self._get_server_rpc()
if rpc is None:
raise RuntimeError("Copilot request response used after RPC connection closed.")
return rpc
async def start_response(
self,
status: int,
status_text: str | None = None,
headers: LlmInferenceHeaders | None = None,
) -> None:
if self.started:
raise RuntimeError("Copilot request response start() called twice.")
if self.finished:
raise RuntimeError("Copilot request response already finished.")
self.started = True
await self._require_rpc().http_response_start(
LlmInferenceHTTPResponseStartRequest(
headers=headers or {},
request_id=self.request_id,
status=status,
status_text=status_text,
)
)
async def write_response(self, data: str | bytes) -> None:
if self.cancelled:
raise RuntimeError("Copilot request was cancelled by the runtime.")
if not self.started:
raise RuntimeError("Copilot request response write() called before start().")
if self.finished:View on GitHub (pinned to cd8cf15dc3)