ZhuLinsen/daily_stock_analysis · critical · RuntimeError

FastAPI server failed to start: {host}:{port}; {startup_erro

Error message

FastAPI server failed to start: {host}:{port}; {startup_error[0]}

What it means

uvicorn runs in a helper thread; any exception thrown during its startup (app import failure, bind error, config error) is captured into startup_error and re-raised on the main thread as RuntimeError. This is the in-loop check that fires as soon as the failure is observed. The appended exception (startup_error[0]) is the real cause.

Source

Thrown at main.py:1256

        if isinstance(install_signal_handlers, bool):
            uvicorn_server.install_signal_handlers = False

    startup_error: list[BaseException] = []

    def run_server():
        try:
            uvicorn_server.run()
        except Exception as exc:  # noqa: BLE001 - surface startup issues to caller promptly
            startup_error.append(exc)

    thread = threading.Thread(target=run_server, daemon=True)
    thread.start()

    timeout_seconds = 3.0
    wait_deadline = time.time() + timeout_seconds
    while time.time() < wait_deadline:
        if startup_error:
            raise RuntimeError(
                f"FastAPI server failed to start: {host}:{port}; {startup_error[0]}"
            )
        if uvicorn_server.started:
            logger.info(f"FastAPI 服务已启动: http://{host}:{port}")
            return
        if not thread.is_alive():
            break
        time.sleep(0.05)

    if startup_error:
        raise RuntimeError(f"FastAPI server failed to start: {host}:{port}; {startup_error[0]}")
    if uvicorn_server.started:
        logger.info(f"FastAPI 服务已启动: http://{host}:{port}")
        return
    if not thread.is_alive():
        raise RuntimeError(f"FastAPI 服务器启动后立即退出: {host}:{port}")

    raise RuntimeError(f"FastAPI 服务在 {timeout_seconds:.1f}s 内未完成启动: {host}:{port}")

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Read the tail of the message after the semicolon — it carries the original exception; fix that first (import error, missing module, etc.).
  2. Reproduce the import directly: python -c "import server" to surface the traceback without the thread wrapper.
  3. If it is a bind race, free the port or change ports and retry.
  4. Run python -m py_compile on files you changed (per repo AGENTS.md backend gate) before starting the server.
Defensive patterns

Strategy: try-catch

Validate before calling

import subprocess, sys

# fail fast: the ASGI app must import cleanly before threading obscures tracebacks
subprocess.run([sys.executable, "-c", "import server"], check=True)

Try / catch

try:
    run_fastapi(host, port, config)
except RuntimeError as e:
    cause = e.__cause__ or e
    logger.exception("uvicorn startup failed: %s", cause)
    # fix the underlying import/config error, then restart — do not blind-retry

Prevention

When it happens

Trigger: The ASGI app import inside the server thread failing (syntax error, missing dependency, circular import in server.py/api), uvicorn failing to bind despite the earlier probe (race with another process grabbing the port), or invalid uvicorn kwargs derived from config (e.g. malformed log_level).

Common situations: Editing server.py or api/ modules introducing an import-time error, then running --serve; a port race where another container grabs the port between probe and run; missing optional dependency only imported at app import time.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/e3e83dee4b9209ab. Report an issue: GitHub.