diff --git a/gateway/platforms/api_server.py b/gateway/platforms/api_server.py index dc60887459..f1def35d9c 100644 --- a/gateway/platforms/api_server.py +++ b/gateway/platforms/api_server.py @@ -62,6 +62,14 @@ MAX_NORMALIZED_TEXT_LENGTH = 65_536 # 64 KB cap for normalized content parts MAX_CONTENT_LIST_SIZE = 1_000 # Max items when content is an array +def _coerce_port(value: Any, default: int = DEFAULT_PORT) -> int: + """Parse a listen port without letting malformed env/config values crash startup.""" + try: + return int(value) + except (TypeError, ValueError): + return default + + def _normalize_chat_content( content: Any, *, _max_depth: int = 10, _depth: int = 0, ) -> str: @@ -573,7 +581,10 @@ class APIServerAdapter(BasePlatformAdapter): super().__init__(config, Platform.API_SERVER) extra = config.extra or {} self._host: str = extra.get("host", os.getenv("API_SERVER_HOST", DEFAULT_HOST)) - self._port: int = int(extra.get("port", os.getenv("API_SERVER_PORT", str(DEFAULT_PORT)))) + raw_port = extra.get("port") + if raw_port is None: + raw_port = os.getenv("API_SERVER_PORT", str(DEFAULT_PORT)) + self._port: int = _coerce_port(raw_port, DEFAULT_PORT) self._api_key: str = extra.get("key", os.getenv("API_SERVER_KEY", "")) self._cors_origins: tuple[str, ...] = self._parse_cors_origins( extra.get("cors_origins", os.getenv("API_SERVER_CORS_ORIGINS", "")), diff --git a/tests/gateway/test_api_server.py b/tests/gateway/test_api_server.py index 74a30541dc..0bc2d043e3 100644 --- a/tests/gateway/test_api_server.py +++ b/tests/gateway/test_api_server.py @@ -240,6 +240,12 @@ class TestAdapterInit: "http://127.0.0.1:3000", ) + def test_invalid_port_from_env_falls_back_to_default(self, monkeypatch): + monkeypatch.setenv("API_SERVER_PORT", "not-a-port") + config = PlatformConfig(enabled=True) + adapter = APIServerAdapter(config) + assert adapter._port == 8642 + # --------------------------------------------------------------------------- # Auth checking