diff --git a/sgl-router/py_src/sglang_router/launch_router.py b/sgl-router/py_src/sglang_router/launch_router.py index 092946a27..f7aaf6dee 100644 --- a/sgl-router/py_src/sglang_router/launch_router.py +++ b/sgl-router/py_src/sglang_router/launch_router.py @@ -97,7 +97,8 @@ class RouterArgs: parser.add_argument( "--worker-urls", type=str, - nargs="+", + nargs="*", + default=[], help="List of worker URLs (e.g., http://worker1:8000 http://worker2:8000)", ) diff --git a/sgl-router/py_test/test_launch_router.py b/sgl-router/py_test/test_launch_router.py index 14a0fa12d..90d8aa664 100644 --- a/sgl-router/py_test/test_launch_router.py +++ b/sgl-router/py_test/test_launch_router.py @@ -90,7 +90,9 @@ class TestLaunchRouter(unittest.TestCase): def test_launch_router_with_empty_worker_urls(self): args = self.create_router_args(worker_urls=[]) - self.run_router_process(args) # Expected error + self.run_router_process( + args + ) # Should start successfully with empty worker list def test_launch_router_with_service_discovery(self): # Test router startup with service discovery enabled but no selectors @@ -279,6 +281,25 @@ class TestLaunchRouter(unittest.TestCase): self.assertEqual(router_args.prefill_selector, {}) self.assertEqual(router_args.decode_selector, {}) + def test_empty_worker_urls_args_parsing(self): + """Test that router accepts no worker URLs and defaults to empty list.""" + import argparse + + from sglang_router.launch_router import RouterArgs + + parser = argparse.ArgumentParser() + RouterArgs.add_cli_args(parser) + + # Test with no --worker-urls argument at all + args = parser.parse_args(["--policy", "random", "--port", "30000"]) + router_args = RouterArgs.from_cli_args(args) + self.assertEqual(router_args.worker_urls, []) + + # Test with explicit empty --worker-urls + args = parser.parse_args(["--worker-urls", "--policy", "random"]) + router_args = RouterArgs.from_cli_args(args) + self.assertEqual(router_args.worker_urls, []) + if __name__ == "__main__": unittest.main()