reflex-dev/reflex · error · RuntimeError

Backend is not running.

Error message

Backend is not running.

What it means

RuntimeError from AppHarness._poll_for_servers when self.backend is None: it tries to poll the uvicorn server's `servers` and `sockets`, so the backend must have been started first. It guards against polling a backend that was never launched.

Source

Thrown at reflex/testing.py:594

            await asyncio.sleep(step)
        return False

    def _poll_for_servers(self, timeout: TimeoutType = None) -> socket.socket:
        """Poll backend server for listening sockets.

        Args:
            timeout: how long to wait for listening socket.

        Returns:
            first active listening socket on the backend

        Raises:
            RuntimeError: when the backend hasn't started running
            TimeoutError: when server or sockets are not ready
        """
        if self.backend is None:
            msg = "Backend is not running."
            raise RuntimeError(msg)
        backend = self.backend
        # check for servers to be initialized
        if not self._poll_for(
            target=lambda: getattr(backend, "servers", False),
            timeout=timeout,
        ):
            msg = "Backend servers are not initialized."
            raise TimeoutError(msg)
        # check for sockets to be listening
        if not self._poll_for(
            target=lambda: getattr(backend.servers[0], "sockets", False),
            timeout=timeout,
        ):
            msg = "Backend is not listening."
            raise TimeoutError(msg)
        return backend.servers[0].sockets[0]

    def frontend(

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Ensure harness.start() completes and the backend actually launched; check earlier logs for the real backend failure
  2. Assert `harness.backend is not None` before polling/using frontend utilities in custom fixtures
  3. Use the standard `with AppHarness.create(...)` flow rather than manual start ordering
Defensive patterns

Strategy: validation

Validate before calling

if harness.backend is None:
    harness.start()  # or fail fast with a clear message

Type guard

def backend_up(h) -> bool:
    return getattr(h, "backend", None) is not None

Try / catch

try:
    url = harness._poll_for_servers()
except RuntimeError as e:
    if "Backend is not running" in str(e):
        harness.start()
        url = harness._poll_for_servers()
    else:
        raise

Prevention

When it happens

Trigger: Calling _start_frontend or _poll_for_servers before _start_backend ran successfully, or after a failed start where backend was never assigned.

Common situations: Backend startup failed earlier (bad app import, port bind error) and the failure was swallowed; manual orchestration of harness internals in a custom fixture; calling start() with backend intentionally disabled.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/60b94a46b46eb70f. Report an issue: GitHub.