From d9cc076d97683251e6c4eb068e259ace418e562e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 6 May 2026 03:40:17 +0000 Subject: [PATCH] fix(proxy): use basename for reload_includes config pattern Uvicorn's resolve_reload_patterns() calls pathlib.Path.glob(), which raises NotImplementedError on absolute patterns (uvicorn discussion 2156). Passing config_abs (an absolute path) when the config file lived outside cwd crashed startup under --reload. The config_dir is already added to reload_dirs, so using just the basename as the include pattern is sufficient to match the specific config file. --- litellm/proxy/proxy_cli.py | 14 +++++++------- tests/test_litellm/proxy/test_proxy_cli.py | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py index 8f1d8b58f5c..57ba71bf1b9 100644 --- a/litellm/proxy/proxy_cli.py +++ b/litellm/proxy/proxy_cli.py @@ -188,13 +188,13 @@ class ProxyInitializationHelpers: if config_dir and config_dir != cwd: reload_dirs.append(config_dir) options["reload_dirs"] = reload_dirs - # Qualify the config-file pattern with its directory so only the - # specific config file (not any same-named file in cwd) triggers a - # reload when config_dir != cwd. - if config_dir and config_dir != cwd: - config_include = config_abs - else: - config_include = os.path.basename(config_abs) + # Use the basename as the include pattern. Uvicorn's + # resolve_reload_patterns() calls pathlib.Path.glob(), which raises + # NotImplementedError on absolute patterns (uvicorn discussion #2156), + # so an absolute path here would crash startup. The config_dir is + # already added to reload_dirs above, so a basename pattern is enough + # to match the specific config file uvicorn is watching. + config_include = os.path.basename(config_abs) options["reload_includes"] = ["*.py", config_include] return options diff --git a/tests/test_litellm/proxy/test_proxy_cli.py b/tests/test_litellm/proxy/test_proxy_cli.py index dcd3e4b0dc0..4d0df4dedcd 100644 --- a/tests/test_litellm/proxy/test_proxy_cli.py +++ b/tests/test_litellm/proxy/test_proxy_cli.py @@ -161,10 +161,10 @@ class TestProxyInitializationHelpers: assert opts["reload"] is True assert opts["reload_dirs"] == [str(cwd_dir), str(elsewhere)] - # When config lives outside cwd, the reload_includes entry must be the - # absolute path so that a same-named file in cwd does not trigger an - # unintended reload. - assert opts["reload_includes"] == ["*.py", str(config_file)] + # The reload_includes entry must be a relative pattern (basename) + # because uvicorn's resolve_reload_patterns() calls pathlib.Path.glob(), + # which raises NotImplementedError on absolute patterns. + assert opts["reload_includes"] == ["*.py", "proxy.yaml"] @patch("asyncio.run") @patch("builtins.print")