{"record":{"id":"b3cf6fcc1c510482","repo":"unslothai/unsloth","slug":"server-port-unavailable","errorCode":null,"errorMessage":"server_port_unavailable","messagePattern":"server_port_unavailable","errorType":"exception","errorClass":"RuntimeError","httpStatus":409,"severity":"error","filePath":"studio/backend/utils/remote_access_settings.py","lineNumber":273,"sourceCode":"        capture_studio_tunnel_start_admission,\n        get_studio_tunnel_control_token,\n    )\n\n    admission = capture_studio_tunnel_start_admission()\n    if admission is None:\n        raise RuntimeError(\"server_shutting_down\")\n    status = remote_access_status(app_state)\n    current = get_studio_tunnel_control_token()\n    if current[0] != admission[0]:\n        raise RuntimeError(\"server_lifecycle_changed\")\n    if status[\"managed_by\"] == \"settings\" and status[\"state\"] in {\"starting\", \"online\"}:\n        return status\n    if not status[\"can_start\"]:\n        raise RuntimeError(status[\"block_reason\"] or \"operation_in_progress\")\n\n    port = getattr(app_state, \"remote_access_port\", None)\n    if not isinstance(port, int) or port <= 0:\n        raise RuntimeError(\"server_port_unavailable\")\n    if get_studio_tunnel_control_token() != admission:\n        raise RuntimeError(\"server_lifecycle_changed\")\n\n    def _start() -> None:\n        from cloudflare_tunnel import start_studio_tunnel\n        url = start_studio_tunnel(port, managed_by = \"settings\", admission = admission)\n        if url:\n            logger.info(\"Secure link access via Cloudflare: %s\", url)\n\n    _open_remote_access_stop_response_admission()\n    with _worker_lock:\n        if not _worker_is_current(_start_worker, _start_worker_admission, admission):\n            _start_worker = threading.Thread(target = _start, daemon = True)\n            _start_worker_admission = admission\n            _start_worker.start()\n    return remote_access_status(app_state)\n\n","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/remote_access_settings.py#L255-L291","documentation":"Raised by start_remote_access() when app_state.remote_access_port is missing or invalid (not an int, or <= 0). The tunnel needs a concrete local port to expose; without one the start is refused before any worker thread is scheduled. This points at server wiring/configuration, not at the tunnel itself.","triggerScenarios":"Calling start_remote_access(app_state) where app_state.remote_access_port is None (attribute never set), a string like '8080' (fails isinstance int), or 0/negative. Happens when the server was started with an incomplete app_state or a config path that skips the port assignment.","commonSituations":"Custom embedding of the studio server that constructs app_state manually and forgets remote_access_port; config migration dropping the port key; running the server in a mode where the HTTP listener port is determined lazily after settings load.","solutions":["Ensure app_state.remote_access_port is set to the server's actual listening port (positive int) before the settings UI/API is exposed.","If port assignment is lazy, block the Start button / API route until the port is known.","Check server startup logs for a failed or skipped port configuration step."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"port = getattr(app_state, 'remote_access_port', None)\nif not isinstance(port, int) or isinstance(port, bool) or port <= 0:\n    abort(409, 'remote access unavailable until server port is configured')","typeGuard":"def has_valid_remote_access_port(app_state) -> bool:\n    port = getattr(app_state, 'remote_access_port', None)\n    return isinstance(port, int) and not isinstance(port, bool) and port > 0","tryCatchPattern":"try:\n    start_remote_access(app_state)\nexcept RuntimeError as e:\n    if str(e) == 'server_port_unavailable':\n        log.error('app_state.remote_access_port unset — fix server wiring')\n        # config bug: do not retry, fix initialization\n    raise","preventionTips":["Set remote_access_port during app_state construction, before exposing settings routes.","Add a startup assertion that remote_access_port is a positive int so misconfiguration fails fast at boot."],"tags":["configuration","tunnel","remote-access","port","python"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}