diff --git a/agent/subdirectory_hints.py b/agent/subdirectory_hints.py index 858807aba2d..ca96c664cb5 100644 --- a/agent/subdirectory_hints.py +++ b/agent/subdirectory_hints.py @@ -144,7 +144,7 @@ class SubdirectoryHintTracker: if parent == p: break # filesystem root p = parent - except (OSError, ValueError): + except (OSError, ValueError, RuntimeError): pass def _extract_paths_from_command(self, cmd: str, candidates: Set[Path]): @@ -241,11 +241,11 @@ class SubdirectoryHintTracker: rel_path = str(hint_path) try: rel_path = str(hint_path.relative_to(self.working_dir)) - except ValueError: + except (ValueError, RuntimeError): try: rel_path = str(hint_path.relative_to(Path.home())) rel_path = "~/" + rel_path - except ValueError: + except (ValueError, RuntimeError): pass # keep absolute found_hints.append((rel_path, content)) # First match wins per directory (like startup loading) diff --git a/tests/agent/test_subdirectory_hints_tilde.py b/tests/agent/test_subdirectory_hints_tilde.py new file mode 100644 index 00000000000..5c6ad74f0e6 --- /dev/null +++ b/tests/agent/test_subdirectory_hints_tilde.py @@ -0,0 +1,54 @@ +"""Regression tests for the home-directory RuntimeError bug. + +Without the fix to ``agent/subdirectory_hints.py`` (add ``RuntimeError`` to +the three ``except`` clauses around ``Path.expanduser()`` / +``Path.home()``), the first two tests raise ``RuntimeError`` from inside +the hint walker on POSIX systems. + +These tests use pytest's built-in ``tmp_path`` fixture and intentionally +do not depend on the richer ``project`` fixture from +``test_subdirectory_hints.py`` so the file is runnable standalone. +""" + +from agent.subdirectory_hints import SubdirectoryHintTracker + + +class TestSubdirectoryHintTrackerTildeRobustness: + """Regression: literal ``~`` in tool-call args must not crash the walker.""" + + def test_tilde_approximately_in_command_does_not_crash(self, tmp_path): + """LLMs use ``~`` for "approximately" (e.g. ``~500 agencies``). + + ``pathlib.Path('~500-700').expanduser()`` raises ``RuntimeError`` — + the walker must catch this, not propagate it as a tool failure. + """ + tracker = SubdirectoryHintTracker(working_dir=str(tmp_path)) + # Heredoc-style terminal command body containing "~500-700" + # used as "approximately 500-700" + cmd = ( + "cat > out.md <