Skip to content

Commit 8baa240

Browse files
authored
fix: print NFS workaround hint when uv pip install/sync fails (#417)
1 parent ef1d836 commit 8baa240

2 files changed

Lines changed: 74 additions & 2 deletions

File tree

comfy_cli/uv.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,21 @@ def _run(cmd: list[str], cwd: PathLike, check: bool = True) -> subprocess.Comple
1818
def _check_call(cmd: list[str], cwd: PathLike | None = None):
1919
"""uses check_call to run pip, as reccomended by the pip maintainers.
2020
see https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program"""
21-
subprocess.check_call(cmd, cwd=cwd)
21+
try:
22+
subprocess.check_call(cmd, cwd=cwd)
23+
except subprocess.CalledProcessError:
24+
if len(cmd) >= 5 and cmd[1:4] == ["-m", "uv", "pip"] and cmd[4] in ("install", "sync"):
25+
from rich import print as rprint
26+
27+
rprint(
28+
"\n[bold yellow]Hint:[/bold yellow] If you are on a network filesystem "
29+
"(RunPod, NFS, etc.), this may be caused by a known uv issue.\n"
30+
"Try setting one of these environment variables before running comfy:\n"
31+
" [green]export UV_LINK_MODE=copy[/green]\n"
32+
" [green]export UV_CACHE_DIR=<your-workspace>/.cache/uv[/green]\n"
33+
"See https://github.com/astral-sh/uv/issues/12036 for details."
34+
)
35+
raise
2236

2337

2438
_req_name_re: re.Pattern[str] = re.compile(r"require\s([\w-]+)")

tests/uv/test_uv.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import shutil
2+
import subprocess
23
from pathlib import Path
34
from unittest.mock import patch
45

56
import pytest
67

78
from comfy_cli import ui
89
from comfy_cli.constants import GPU_OPTION
9-
from comfy_cli.uv import DependencyCompiler
10+
from comfy_cli.uv import DependencyCompiler, _check_call
1011

1112
hereDir = Path(__file__).parent.resolve()
1213
mockComfyDir = hereDir / "mock_comfy"
@@ -302,3 +303,60 @@ def test_skip_torch_install_deps_no_extra_index_url():
302303
depComp.install_deps()
303304
cmd = mock_check_call.call_args[0][0]
304305
assert "--extra-index-url" not in cmd
306+
307+
308+
def test_check_call_prints_nfs_hint_on_uv_install_failure(capsys):
309+
"""When a uv pip install command fails, _check_call should print an NFS hint."""
310+
cmd = ["python", "-m", "uv", "pip", "install", "--requirement", "reqs.txt"]
311+
with patch("subprocess.check_call", side_effect=subprocess.CalledProcessError(2, cmd)):
312+
with pytest.raises(subprocess.CalledProcessError):
313+
_check_call(cmd)
314+
315+
captured = capsys.readouterr().out
316+
assert "network filesystem" in captured
317+
assert "UV_LINK_MODE" in captured
318+
assert "UV_CACHE_DIR" in captured
319+
320+
321+
def test_check_call_prints_nfs_hint_on_uv_sync_failure(capsys):
322+
"""When a uv pip sync command fails, _check_call should print an NFS hint."""
323+
cmd = ["python", "-m", "uv", "pip", "sync", "reqs.txt"]
324+
with patch("subprocess.check_call", side_effect=subprocess.CalledProcessError(2, cmd)):
325+
with pytest.raises(subprocess.CalledProcessError):
326+
_check_call(cmd)
327+
328+
captured = capsys.readouterr().out
329+
assert "network filesystem" in captured
330+
331+
332+
def test_check_call_no_hint_for_non_uv_failure(capsys):
333+
"""Non-uv commands should not trigger the NFS hint."""
334+
cmd = ["python", "-m", "pip", "install", "requests"]
335+
with patch("subprocess.check_call", side_effect=subprocess.CalledProcessError(1, cmd)):
336+
with pytest.raises(subprocess.CalledProcessError):
337+
_check_call(cmd)
338+
339+
captured = capsys.readouterr().out
340+
assert "network filesystem" not in captured
341+
342+
343+
def test_check_call_no_hint_on_uv_compile_failure(capsys):
344+
"""uv pip compile failures should not trigger the NFS hint (only install/sync)."""
345+
cmd = ["python", "-m", "uv", "pip", "compile", "reqs.in"]
346+
with patch("subprocess.check_call", side_effect=subprocess.CalledProcessError(1, cmd)):
347+
with pytest.raises(subprocess.CalledProcessError):
348+
_check_call(cmd)
349+
350+
captured = capsys.readouterr().out
351+
assert "network filesystem" not in captured
352+
353+
354+
def test_check_call_no_hint_for_pip_install_uv(capsys):
355+
"""'pip install uv' must not trigger the hint even though 'uv' and 'install' are both present."""
356+
cmd = ["python", "-m", "pip", "install", "--upgrade", "pip", "uv"]
357+
with patch("subprocess.check_call", side_effect=subprocess.CalledProcessError(1, cmd)):
358+
with pytest.raises(subprocess.CalledProcessError):
359+
_check_call(cmd)
360+
361+
captured = capsys.readouterr().out
362+
assert "network filesystem" not in captured

0 commit comments

Comments
 (0)