microsoft/autogen · error · RuntimeError
Host runtime is already started.
Error message
Host runtime is already started.
What it means
GrpcWorkerAgentRuntimeHost.start() launches the gRPC server as a background asyncio task and guards against double-start: if self._serve_task is already set it raises RuntimeError('Host runtime is already started.'). The flag is only cleared by stop(), so calling start() twice on a live host is rejected.
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime_host.py:36
class GrpcWorkerAgentRuntimeHost:
def __init__(self, address: str, extra_grpc_config: Optional[ChannelArgumentType] = None) -> None:
self._server = grpc.aio.server(options=extra_grpc_config)
self._servicer = GrpcWorkerAgentRuntimeHostServicer()
agent_worker_pb2_grpc.add_AgentRpcServicer_to_server(self._servicer, self._server)
self._server.add_insecure_port(address)
self._address = address
self._serve_task: asyncio.Task[None] | None = None
async def _serve(self) -> None:
await self._server.start()
logger.info(f"Server started at {self._address}.")
await self._server.wait_for_termination()
def start(self) -> None:
"""Start the server in a background task."""
if self._serve_task is not None:
raise RuntimeError("Host runtime is already started.")
self._serve_task = asyncio.create_task(self._serve())
async def stop(self, grace: int = 5) -> None:
"""Stop the server."""
if self._serve_task is None:
raise RuntimeError("Host runtime is not started.")
await self._server.stop(grace=grace)
self._serve_task.cancel()
try:
await self._serve_task
except asyncio.CancelledError:
pass
logger.info("Server stopped.")
self._serve_task = None
async def stop_when_signal(
self, grace: int = 5, signals: Sequence[signal.Signals] = (signal.SIGTERM, signal.SIGINT)
) -> None:View on GitHub (pinned to 027ecf0a37)
Solutions
- Call start() exactly once per host lifecycle; track started state and skip if already running
- Recreate the host object (GrpcWorkerAgentRuntimeHost(address)) for a fresh start instead of re-starting
- In fixtures, pair start()/stop() with setup/teardown so each test gets a stopped or fresh host
- Guard with 'if host._serve_task is None' equivalent state you maintain, or try/except RuntimeError as a no-op signal
Example fix
# before host.start() host.start() # RuntimeError: Host runtime is already started. # after host.start() # ... later, to restart: await host.stop() host.start()
Defensive patterns
Strategy: validation
Validate before calling
def start_once(host) -> None:
if getattr(host, '_serve_task', None) is None:
host.start() Try / catch
try:
host.start()
except RuntimeError as e:
if 'already started' in str(e):
pass # idempotent start
else:
raise Prevention
- Call start() once per host lifecycle; track state explicitly
- Pair start/stop in fixtures rather than re-starting
- Restart cycles go start -> stop -> start, never start -> start
- Keep host creation and start adjacent in code so re-runs recreate both
When it happens
Trigger: Calling host.start() a second time before host.stop(); re-running setup code (notebook cell, test fixture) against a host object that is still serving; orchestration code that retries initialization by calling start() again after a partial failure where the task was already created.
Common situations: Notebook cells re-executed without recreating the host; pytest fixtures calling start() per test on a session-scoped host; retry wrappers around startup logic that treat any exception as 'try start again'.
Related errors
- Host runtime is not started.
- Runtime is already started
- Connection is not open.
- Runtime is already running.
- Runtime is not running.
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/0252dc356ebdfef9.
Report an issue: GitHub.