Skip to content

fix(bundle): resolve file:// download_url via the file-URL helper#3344

Open
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/bundle-download-manifest-file-url
Open

fix(bundle): resolve file:// download_url via the file-URL helper#3344
jawwad-ali wants to merge 1 commit into
github:mainfrom
jawwad-ali:fix/bundle-download-manifest-file-url

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

Description

A catalog entry whose download_url is a file:// URL — the canonical URI Python itself produces via Path.as_uri() — always fails to resolve:

# _download_manifest, commands/bundle/__init__.py
local = Path(parsed.path if scheme == "file" else url)

Raw parsed.path has two problems:

  1. Windows: every path breaks. file:///C:/Users/x/bundle.ymlparsed.path = /C:/Users/x/bundle.ymlPath(...) = \C:\Users\x\bundle.yml, a leading-slash drive path that never exists.
  2. Every OS: percent-encoding is never decoded. file:///home/user/my%20bundles/bundle.yml keeps the literal %20.

Reproduced on main @ bba473c:

BundlerError: Bundle manifest not found: \C:\Users\...\my%20bundles\bundle.yml

The repo already fixed this exact class of bug for catalog file:// URLs: bundler/services/adapters.py::_file_url_to_path percent-decodes via url2pathname and preserves netloc for UNC/drive URLs (used by make_catalog_fetcher). _download_manifest is the one call site that never got the same treatment.

Fix

Route the file scheme through the existing helper (lazy import, matching the file's style); the bare-path/Windows-drive branch keeps Path(url) unchanged.

Testing

  • New test_download_manifest_resolves_file_url: manifest under my bundles/ (space in dirname so the percent-encoding failure reproduces on POSIX CI too), download_url=path.as_uri() → resolves bundle.id. Fails before (Bundle manifest not found: \C:\...my%20bundles\..., verified by source-stash), passes after.
  • New test_download_manifest_bare_windows_path_still_resolves: pins the non-URL branch (passes before and after).
  • Full tests/integration/test_bundler_local_install.py: 8 passed. uvx ruff check clean.

AI Disclosure

  • I did use AI assistance (describe below)

Found and fixed with Claude Code (Claude Fable 5) under my direction. AI identified the raw-parsed.path divergence from the adapters helper; I reproduced the failure on Windows, verified fail-before/pass-after, and reviewed the diff before submitting.

_download_manifest built the local path from raw parsed.path, which
keeps the leading slash of file:///C:/x (yielding a \C:\x path that
never exists on Windows) and skips percent-decoding (my%20bundles stays
encoded on every OS) — so a catalog entry whose download_url is the
canonical URI Python itself produces via Path.as_uri() always fails
with 'Bundle manifest not found'. Route the file scheme through the
existing bundler.services.adapters._file_url_to_path helper, which
already handles drive letters, UNC hosts, and percent-decoding for
catalog file:// URLs (make_catalog_fetcher). The bare-path branch is
unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jawwad-ali jawwad-ali requested a review from mnriem as a code owner July 5, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant