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

  1. Call start() exactly once per host lifecycle; track started state and skip if already running
  2. Recreate the host object (GrpcWorkerAgentRuntimeHost(address)) for a fresh start instead of re-starting
  3. In fixtures, pair start()/stop() with setup/teardown so each test gets a stopped or fresh host
  4. 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

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


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/0252dc356ebdfef9. Report an issue: GitHub.