From a5bd20c65bbb6ca15ec72b8eede1c9e8e58d65e1 Mon Sep 17 00:00:00 2001 From: danshapiro Date: Thu, 13 Aug 2026 23:54:07 -0700 Subject: [PATCH] fix(paths): recognize Windows absolute paths (drive-letter/UNC) in parse_uri C:/..., C:\..., and \\server\share\... URIs previously fell through to the package-name heuristic, so no source handler claimed them and resolution failed with 'No handler for URI' on native Windows. This surfaced when settings.yaml referenced local behaviors/bundles via Windows paths, and when relative module entries inside cached bundles were resolved to absolute OS path strings (strict mode then aborted session startup). Fixes https://github.com/microsoft/amplifier/issues/374 --- amplifier_foundation/paths/resolution.py | 9 ++++++++ tests/test_paths.py | 28 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/amplifier_foundation/paths/resolution.py b/amplifier_foundation/paths/resolution.py index 92e88ccf..f7216e53 100644 --- a/amplifier_foundation/paths/resolution.py +++ b/amplifier_foundation/paths/resolution.py @@ -105,6 +105,8 @@ def parse_uri(uri: str) -> ParsedURI: - zip+file:///local/archive.zip#subdirectory=path/inside - file:///path/to/file - /absolute/path + - C:\absolute\path or C:/absolute/path (Windows) + - \\server\share\path (Windows UNC) - ./relative/path - package-name - package/subpath @@ -136,6 +138,13 @@ def parse_uri(uri: str) -> ParsedURI: if uri.startswith("./") or uri.startswith("../"): return ParsedURI(scheme="file", host="", path=uri, ref="", subpath="") + # Handle Windows absolute paths (drive-letter or UNC) + is_drive_path = ( + len(uri) >= 3 and uri[0].isalpha() and uri[1] == ":" and uri[2] in "/\\" + ) + if is_drive_path or uri.startswith("\\\\"): + return ParsedURI(scheme="file", host="", path=uri, ref="", subpath="") + # Handle http/https URLs if uri.startswith("http://") or uri.startswith("https://"): parsed = urlparse(uri) diff --git a/tests/test_paths.py b/tests/test_paths.py index ae9a059b..eeaa70d8 100644 --- a/tests/test_paths.py +++ b/tests/test_paths.py @@ -135,6 +135,34 @@ def test_relative_path(self) -> None: assert result.scheme == "file" assert result.path == "./bundles/my-bundle" + def test_windows_drive_letter_path(self) -> None: + """Parses Windows drive-letter paths as file URIs.""" + result = parse_uri("C:/Users/test/bundle") + assert result.scheme == "file" + assert result.path == "C:/Users/test/bundle" + assert result.is_file + + def test_windows_drive_letter_backslash_path(self) -> None: + """Parses Windows backslash drive-letter paths as file URIs.""" + result = parse_uri(r"C:\Users\test\bundle") + assert result.scheme == "file" + assert result.path == r"C:\Users\test\bundle" + assert result.is_file + + def test_windows_unc_path(self) -> None: + """Parses Windows UNC paths as file URIs.""" + result = parse_uri(r"\\server\share\bundle") + assert result.scheme == "file" + assert result.path == r"\\server\share\bundle" + assert result.is_file + + def test_windows_file_uri_with_drive_letter(self) -> None: + """Parses file:// URIs containing a drive letter.""" + result = parse_uri("file://C:/Users/test/bundle") + assert result.scheme == "file" + assert result.path == "C:/Users/test/bundle" + assert result.is_file + class TestNormalizePath: """Tests for normalize_path function."""