{"record":{"id":"ee832d57b87f5fa1","repo":"microsoft/autogen","slug":"runtime-is-already-running-ee832d","errorCode":null,"errorMessage":"Runtime is already running.","messagePattern":"Runtime is already running\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py","lineNumber":264,"sourceCode":"        self._pending_requests: Dict[str, Future[Any]] = {}\n        self._pending_requests_lock = asyncio.Lock()\n        self._next_request_id = 0\n        self._host_connection: HostConnection | None = None\n        self._background_tasks: Set[Task[Any]] = set()\n        self._subscription_manager = SubscriptionManager()\n        self._serialization_registry = SerializationRegistry()\n        self._extra_grpc_config = extra_grpc_config or []\n        self._agent_instance_types: Dict[str, Type[Agent]] = {}\n\n        if payload_serialization_format not in {JSON_DATA_CONTENT_TYPE, PROTOBUF_DATA_CONTENT_TYPE}:\n            raise ValueError(f\"Unsupported payload serialization format: {payload_serialization_format}\")\n\n        self._payload_serialization_format = payload_serialization_format\n\n    async def start(self) -> None:\n        \"\"\"Start the runtime in a background task.\"\"\"\n        if self._running:\n            raise ValueError(\"Runtime is already running.\")\n        logger.info(f\"Connecting to host: {self._host_address}\")\n        self._host_connection = await HostConnection.from_host_address(\n            self._host_address, extra_grpc_config=self._extra_grpc_config\n        )\n        logger.info(\"Connection established\")\n        if self._read_task is None:\n            self._read_task = asyncio.create_task(self._run_read_loop())\n        self._running = True\n\n    def _raise_on_exception(self, task: Task[Any]) -> None:\n        exception = task.exception()\n        if exception is not None:\n            raise exception\n\n    async def _run_read_loop(self) -> None:\n        logger.info(\"Starting read loop\")\n        assert self._host_connection is not None\n        # TODO: catch exceptions and reconnect","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py#L246-L282","documentation":"GrpcWorkerAgentRuntime.start() is not idempotent: it checks the internal _running flag and raises ValueError('Runtime is already running.') if start() is called again without an intervening stop(). This protects the single read-loop task and host connection from being duplicated.","triggerScenarios":"Calling `await runtime.start()` twice, e.g. in a retry wrapper, a Jupyter notebook re-execution, or after a framework (like an agent runtime host) already started the runtime for you.","commonSituations":"Notebook workflows where a cell is re-run; orchestration code that starts the runtime per-task inside a long-lived process; wrapping start() in a generic retry loop.","solutions":["Track started state yourself and only call start() once per lifecycle","Catch/avoid: check runtime state or guard with try/except ValueError if double-start is possible","Call `await runtime.stop()` (and optionally `await runtime.close()`) before restarting in restart loops"],"exampleFix":"# before\nawait runtime.start()  # ValueError on second call\n\n# after\nstarted = False\nif not started:\n    await runtime.start()\n    started = True","handlingStrategy":"validation","validationCode":"# start only if not running (track locally; _running is private)\nstarted = False\nasync def ensure_started(runtime):\n    global started\n    if not started:\n        await runtime.start()\n        started = True","typeGuard":null,"tryCatchPattern":"try:\n    await runtime.start()\nexcept ValueError as e:\n    if \"already running\" in str(e):\n        pass  # idempotent start\n    else:\n        raise","preventionTips":["Wrap runtime lifecycle in an async context manager so start() is called exactly once","Avoid retry loops around start() without state tracking","In notebooks, reuse one runtime across cells instead of re-running start()"],"tags":["python","autogen","grpc","lifecycle","state-management"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}