HKUDS/DeepTutor · error · SystemExit

start.frontend_restart_failed

Error message

start.frontend_restart_failed

What it means

start() found a previously recorded source frontend process but its HTTP endpoint failed the health probe, and the attempt to stop that unhealthy frontend failed, so the restart cannot proceed. The message is the i18n key start.frontend_restart_failed formatted with url and pid.

Source

Thrown at deeptutor/runtime/launcher.py:988

        runtime_env.get("NEXT_PUBLIC_API_BASE_EXTERNAL")
        or runtime_env.get("NEXT_PUBLIC_API_BASE")
        or backend_url
    )
    frontend = _resolve_frontend(
        runtime_home,
        frontend_port,
        api_base=api_base,
        auth_enabled=auth_enabled,
        dev=dev,
    )
    existing_frontend = _detect_existing_source_frontend(frontend)
    if existing_frontend is not None and not _http_ready(
        existing_frontend.url, timeout=FRONTEND_REUSE_PROBE_TIMEOUT
    ):
        pid = existing_frontend.pid if existing_frontend.pid is not None else "unknown"
        _log(_t("start.restarting_frontend", url=existing_frontend.url, pid=pid))
        if not _stop_unhealthy_source_frontend(existing_frontend):
            raise SystemExit(
                _t("start.frontend_restart_failed", url=existing_frontend.url, pid=pid)
            )
        existing_frontend = None
    if existing_frontend is not None:
        frontend_port = existing_frontend.port

    resolved_backend, resolved_frontend = _resolve_port_conflicts(
        backend_port=backend_port,
        frontend_port=frontend_port,
        check_frontend=existing_frontend is None,
        settings_dir=settings.settings_dir,
    )
    if (resolved_backend, resolved_frontend) != (backend_port, frontend_port):
        backend_port, frontend_port = resolved_backend, resolved_frontend
        runtime_env = export_runtime_settings_to_env(overwrite=True)
        backend_url = f"http://127.0.0.1:{backend_port}"
        api_base = (
            runtime_env.get("NEXT_PUBLIC_API_BASE_EXTERNAL")

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Kill whatever occupies the recorded port: `lsof -i :<port>` then kill it, and rerun deeptutor start
  2. Clear the stale frontend state file under the DeepTutor runtime home (data/user or runtime state dir) so a fresh frontend is launched
  3. If it's your own orphaned vite/npm process, `pkill -f "npm run dev"` then restart
  4. Pass a different frontend port to avoid the conflicting process

Example fix

# before
deeptutor start  # start.frontend_restart_failed
# after
lsof -ti :5173 | xargs kill
deeptutor start
Defensive patterns

Strategy: fallback

Validate before calling

import socket
def port_free(port: int) -> bool:
    with socket.socket() as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            s.bind(("127.0.0.1", port)); return True
        except OSError:
            return False

Try / catch

try:
    start()
except SystemExit as e:
    if "frontend_restart_failed" in str(getattr(e, "code", "")):
        # clean stale state / ports, then retry once
        clear_frontend_state(); start()

Prevention

When it happens

Trigger: A stale frontend state file exists (from a previous crashed/killed run) pointing at a port that no longer serves HTTP, and _stop_unhealthy_source_frontend returns False — e.g. the pid is dead but the port is occupied by another process, or the pid file can't be resolved/killed.

Common situations: An orphaned npm/vite dev server from a previous session holding the port; machine rebooted leaving stale state; another application bound to the recorded frontend port; permission denied when signaling the old process.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/04168d95f629656c. Report an issue: GitHub.