You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
uv pip install --python <venv> fails for a cpython-*-emscripten-wasm32-musl venv on Windows — malformed path mixing POSIX and Windows conventions #21199
uv venv --python cpython-3.13.2-emscripten-wasm32-musl creates a venv with a Windows-native layout (Lib\site-packages, Scripts\), but a subsequent uv pip install --python <that-venv> crashes trying to create a malformed, POSIX-style path (//lib/python3.13/site-packages\) that doesn't match the venv it just created.
Installs into myvenv\Lib\site-packages (matching the layout uv venv itself just created), or errors clearly if that's unsupported.
Actual
Using Python 3.13.2 environment at: /
Resolved 1 package in 514ms
Prepared 1 package in 63ms
error: Failed to install: click-8.4.2-py3-none-any.whl (click==8.4.2)
Caused by: Failed to create directory `//lib/python3.13/site-packages\`
Caused by: failed to create directory `//lib/python3.13/site-packages\`: The network path was not found. (os error 53)
Two things stand out:
The resolved "environment at" is /, not the real venv path — same result whether --python points at the venv directory or directly at myvenv\Scripts\python.exe.
The target path mixes forward slashes (matching the emscripten target's own embedded POSIX scheme) with a trailing backslash, and isn't rooted anywhere valid on Windows (// reads as a UNC prefix, hence "network path not found").
This looks like a disagreement between two parts of uv: uv venv correctly uses the host's layout convention for the venv skeleton, but uv pip install --python for that same venv instead consults the target interpreter's own embedded (POSIX) scheme — and the two don't agree.
Related
Possibly adjacent to #19963 (closed as "working as intended" for --prefix + --python-platform), but this is a different code path — a real venv with its own pyvenv.cfg already exists here, created by uv venv itself for this exact interpreter, and uv pip install --python still doesn't agree with it.
Version
uv 0.12.5 (210d1f6 2026-08-14 x86_64-pc-windows-msvc), Windows
Dug a bit further into the source to narrow down where this might live, in case it's useful.
uv venv itself computes the venv's scheme correctly — crates/uv-virtualenv/src/virtualenv.rs:625 builds VirtualEnvironment { scheme: Scheme { purelib: location.join(&interpreter.virtualenv().purelib), ... } }, which is why the venv this creates genuinely has Lib\site-packages on Windows (confirmed via Get-ChildItem/pyvenv.cfg above). But that computed Scheme only exists in memory for that one uv venv invocation — it's never persisted to disk (pyvenv.cfg doesn't record it).
A later, separate uv pip install --python <that venv> process has to independently re-derive the same layout, presumably by reading pyvenv.cfg's home = ... line and re-introspecting the interpreter it points at (InterpreterInfo::query/with_virtualenv in crates/uv-python/src/interpreter.rs).
Working hypothesis: the two code paths disagree on what determines the layout. uv venv's own creation logic appears to use the host OS (correctly landing on Lib\site-packages for a Windows host). The re-derivation path used by later commands may instead be keying off the interpreter's own self-reported os_name marker — which for a Pyodide/emscripten CPython build is almost certainly posix, regardless of the host it's actually running on. That would explain the exact malformed path observed (//lib/python3.13/site-packages\) and would be invisible for every normal interpreter, since a native interpreter's self-reported OS always matches its real host by definition — this foreign-target case is the one place that assumption breaks.
I haven't pinned the exact line where the interpreter's os_name marker feeds into the second code path's layout decision, and don't have a Rust build set up to verify by patching and testing directly, but wanted to share the narrowed-down lead in case it's a useful starting point.
Hey, I’d be interested in taking a look at this. The Windows/Pyodide venv path mismatch seems pretty well isolated, especially around the difference between venv creation and later --python re-discovery. Would you be open to a PR if I can reproduce it on current main and add a regression test?
Activity
mittalpk commentedon Aug 18, 2026
Dug a bit further into the source to narrow down where this might live, in case it's useful.
uv venvitself computes the venv's scheme correctly —crates/uv-virtualenv/src/virtualenv.rs:625buildsVirtualEnvironment { scheme: Scheme { purelib: location.join(&interpreter.virtualenv().purelib), ... } }, which is why the venv this creates genuinely hasLib\site-packageson Windows (confirmed viaGet-ChildItem/pyvenv.cfgabove). But that computedSchemeonly exists in memory for that oneuv venvinvocation — it's never persisted to disk (pyvenv.cfgdoesn't record it).A later, separate
uv pip install --python <that venv>process has to independently re-derive the same layout, presumably by readingpyvenv.cfg'shome = ...line and re-introspecting the interpreter it points at (InterpreterInfo::query/with_virtualenvincrates/uv-python/src/interpreter.rs).Working hypothesis: the two code paths disagree on what determines the layout.
uv venv's own creation logic appears to use the host OS (correctly landing onLib\site-packagesfor a Windows host). The re-derivation path used by later commands may instead be keying off the interpreter's own self-reportedos_namemarker — which for a Pyodide/emscripten CPython build is almost certainlyposix, regardless of the host it's actually running on. That would explain the exact malformed path observed (//lib/python3.13/site-packages\) and would be invisible for every normal interpreter, since a native interpreter's self-reported OS always matches its real host by definition — this foreign-target case is the one place that assumption breaks.I haven't pinned the exact line where the interpreter's
os_namemarker feeds into the second code path's layout decision, and don't have a Rust build set up to verify by patching and testing directly, but wanted to share the narrowed-down lead in case it's a useful starting point.joshuavetos commentedon Aug 30, 2026
Hey, I’d be interested in taking a look at this. The Windows/Pyodide venv path mismatch seems pretty well isolated, especially around the difference between venv creation and later --python re-discovery. Would you be open to a PR if I can reproduce it on current main and add a regression test?