{"record":{"id":"f0f48470be8dfb7c","repo":"github/copilot-sdk","slug":"cli-process-not-started-f0f484","errorCode":null,"errorMessage":"CLI process not started","messagePattern":"CLI process not started","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/copilot/client.py","lineNumber":4594,"sourceCode":"            await self._connect_via_tcp()\n        log_timing(\n            logger,\n            logging.DEBUG,\n            \"CopilotClient._connect_to_server transport setup complete\",\n            setup_start,\n        )\n\n    async def _connect_via_stdio(self) -> None:\n        \"\"\"\n        Connect to the CLI server via stdio pipes.\n\n        Creates a JSON-RPC client using the CLI process's stdin/stdout.\n\n        Raises:\n            RuntimeError: If the CLI process is not started.\n        \"\"\"\n        if not self._process:\n            raise RuntimeError(\"CLI process not started\")\n\n        # Create JSON-RPC client with the process\n        self._client = JsonRpcClient(self._process)\n        self._client.on_close = self._handle_connection_close\n        self._rpc = ServerRpc(self._client)\n\n        # Set up notification handler for session events\n        # Note: This handler is called from the event loop (thread-safe scheduling)\n        def handle_notification(method: str, params: dict):\n            if method == \"session.event\":\n                session_id = params[\"sessionId\"]\n                event_dict = params[\"event\"]\n                # Convert dict to SessionEvent object\n                event = session_event_from_dict(event_dict)\n                with self._sessions_lock:\n                    session = self._sessions.get(session_id)\n                if session:\n                    session._dispatch_event(event)","sourceCodeStart":4576,"sourceCodeEnd":4612,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/python/copilot/client.py#L4576-L4612","documentation":"RuntimeError raised when creating the stdio JSON-RPC client if self._process is None, i.e. no CLI subprocess exists. The stdio transport wires JSON-RPC over the process's stdin/stdout, which cannot work without a started process.","triggerScenarios":"Calling _create_stdio_client() (stdio connect path) before the CLI process was spawned, or after it was stopped/cleared (self._process reset to None).","commonSituations":"Calling connect with stdio mode before start(); reusing a client after stop()/disconnect; a failed prior start left _process None; incorrect ordering of internal API calls in custom tooling.","solutions":["Start the CLI process (client.start() or the appropriate spawn call) before creating the stdio client","Do not reuse a client instance after stop(); create a new CopilotClient","Ensure the start() await completed successfully before calling stdio connect","Check custom code isn't setting self._process = None on cleanup prematurely"],"exampleFix":"// before\nawait client._create_stdio_client()  # no process yet -> RuntimeError\n\n// after\nawait client.start()          # spawns CLI process\nawait client._create_stdio_client()","handlingStrategy":"try-catch","validationCode":"assert client._process is not None, \"start() must complete before stdio connect\"","typeGuard":"def has_process(client) -> bool:\n    return getattr(client, \"_process\", None) is not None","tryCatchPattern":"try:\n    await client._create_stdio_client()\nexcept RuntimeError as e:\n    if \"CLI process not started\" in str(e):\n        await client.start()\n        await client._create_stdio_client()\n    else:\n        raise","preventionTips":["Await start() before any connect call","Create a new client after stop() instead of reconnecting the old one","Keep transport mode (stdio/tcp/ffi) consistent across start and connect","Encapsulate start+connect in one helper so ordering can't drift"],"tags":["subprocess","stdio","lifecycle"],"backgroundTag":"invalid-state-transition","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}