Summary
On Windows, if the managed-Python minor version link junction (e.g. cpython-3.13-windows-x86_64-none) becomes dangling, every subsequent uv python install / uv python install --reinstall / uv run fails with:
error: Missing expected target directory for Python minor version link at C:\Users\<user>\AppData\Roaming\uv\python\cpython-3.13.13-windows-x86_64-none
uv does not self-heal this. --reinstall re-downloads and re-extracts the interpreter, but still fails at the link step, and re-creates a junction that also does not resolve. Even deleting the patch directory and .temp entirely and running a clean uv python install 3.13 reproduces the identical error. The only thing that fixes it is manually deleting the dangling junction and recreating it with a native Windows junction.
Environment
On-disk state when broken
%APPDATA%\Roaming\uv\python\:
cpython-3.13.13-windows-x86_64-none — real directory, complete and working. python.exe -V => Python 3.13.13 (exit 0); full stdlib present.
cpython-3.13-windows-x86_64-none — a Junction whose Target correctly reads ...\cpython-3.13.13-windows-x86_64-none, but which enumerates 0 children (dangling at the OS level / does not resolve).
So the interpreter is fine; only the minor-version-link junction is broken, and that one broken junction poisons discovery and install.
Reproduction (verbose)
uv python install 3.13 --reinstall -v (stderr):
DEBUG Found download `cpython-3.13.13-windows-x86_64-none` for request `3.13 (cpython-3.13-windows-x86_64-none)`
DEBUG Downloading https://releases.astral.sh/github/python-build-standalone/releases/download/20260510/cpython-3.13.13%2B20260510-x86_64-pc-windows-msvc-install_only_stripped.tar.gz
DEBUG Extracting ... to temporary location: ...\uv\python\.temp\.tmpXXXXXX
Downloading cpython-3.13.13-windows-x86_64-none (download) (20.8MiB)
Downloaded cpython-3.13.13-windows-x86_64-none (download)
DEBUG Removing existing directory: ...\uv\python\cpython-3.13.13-windows-x86_64-none
DEBUG Moving ...\uv\python\.temp\.tmpXXXXXX\python to ...\uv\python\cpython-3.13.13-windows-x86_64-none
DEBUG Inspecting existing executable at `C:\Users\<user>\.local\bin\python3.13.exe`
error: Missing expected target directory for Python minor version link at ...\uv\python\cpython-3.13.13-windows-x86_64-none
Observations:
- The patch directory is re-created by the move and is valid, yet the install still fails at the minor-version-link step (exit code 2).
--reinstall does not remove/replace the pre-existing dangling cpython-3.13-... junction; the run ends with that junction still present and still enumerating 0 children.
- Deleting the patch dir and
.temp, then uv python install 3.13 from a clean state, fails identically.
- When uv itself (re)creates the
cpython-3.13-... junction during install, the result does not resolve (0 children). A junction created manually to the same target (New-Item -ItemType Junction / mklink /J) does resolve.
Workaround that actually fixes it
$base = "$env:APPDATA\uv\python"
$link = Join-Path $base 'cpython-3.13-windows-x86_64-none'
$patch = Join-Path $base 'cpython-3.13.13-windows-x86_64-none'
[System.IO.Directory]::Delete($link, $false) # remove the dangling junction only (leaves the patch dir intact)
New-Item -ItemType Junction -Path $link -Target $patch | Out-Null
After this, uv python list --only-installed shows cpython-3.13.13 and uv run/uv python find use it normally.
Suggested fix
ensure_minor_version_link() should be idempotent / self-healing on Windows: if a minor-version-link junction already exists but does not resolve to a valid target (dangling reparse point), remove and recreate it rather than erroring with "Missing expected target directory". Discovery (find_all) could likewise treat a non-resolving managed-install junction as repairable/ignorable instead of hard-failing the whole operation.
Possibly related
Summary
On Windows, if the managed-Python minor version link junction (e.g.
cpython-3.13-windows-x86_64-none) becomes dangling, every subsequentuv python install/uv python install --reinstall/uv runfails with:uv does not self-heal this.
--reinstallre-downloads and re-extracts the interpreter, but still fails at the link step, and re-creates a junction that also does not resolve. Even deleting the patch directory and.tempentirely and running a cleanuv python install 3.13reproduces the identical error. The only thing that fixes it is manually deleting the dangling junction and recreating it with a native Windows junction.Environment
%APPDATA%\Roaming\uv\pythonuv --directory <ext> run <pkg>(pinned to Python 3.13 via.python-version); every spawn hit the error and the MCP server disconnected.Directoryattributes, no OneDrive placeholder /Offline/SparseFilereparse attributes.On-disk state when broken
%APPDATA%\Roaming\uv\python\:cpython-3.13.13-windows-x86_64-none— real directory, complete and working.python.exe -V=>Python 3.13.13(exit 0); full stdlib present.cpython-3.13-windows-x86_64-none— a Junction whoseTargetcorrectly reads...\cpython-3.13.13-windows-x86_64-none, but which enumerates 0 children (dangling at the OS level / does not resolve).So the interpreter is fine; only the minor-version-link junction is broken, and that one broken junction poisons discovery and install.
Reproduction (verbose)
uv python install 3.13 --reinstall -v(stderr):Observations:
--reinstalldoes not remove/replace the pre-existing danglingcpython-3.13-...junction; the run ends with that junction still present and still enumerating 0 children..temp, thenuv python install 3.13from a clean state, fails identically.cpython-3.13-...junction during install, the result does not resolve (0 children). A junction created manually to the same target (New-Item -ItemType Junction/mklink /J) does resolve.Workaround that actually fixes it
After this,
uv python list --only-installedshowscpython-3.13.13anduv run/uv python finduse it normally.Suggested fix
ensure_minor_version_link()should be idempotent / self-healing on Windows: if a minor-version-link junction already exists but does not resolve to a valid target (dangling reparse point), remove and recreate it rather than erroring with "Missing expected target directory". Discovery (find_all) could likewise treat a non-resolving managed-install junction as repairable/ignorable instead of hard-failing the whole operation.Possibly related
uv python installpublishes managed Python before finalization, allowinguv python findto race and observe incomplete installs #19329 —uv python installpublishes the managed Python before finalization (ensure_minor_version_link()runs late); an interrupted/raced install is a plausible way to end up with a published patch dir + a missing/broken minor-version link, i.e. the precondition for this bug.os error 448; this report is a different (non-OneDrive) manifestation at the validation site.