astral-sh / astral-sh/uv

uv fails to find workspace root for nested packages

Open
#16,640 3 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
89.8k
Forks
3.6k
Avg merge
1d 21m
Merged PRs (30d)
353

Description

### Summary

In a multi-level workspace, uv appears to treat nested members differently from top-level members:
```
mkdir -p foo/a/b
cd foo; uv init
cd a; uv init
cd b; uv init

cd ../ # we're under 'foo/a' now
uv sync # creates .venv and uv.lock at the workspace root 'foo/'

cd b
uv sync # creates a new .venv and uv.lock under 'foo/a/b'
```

I would expect that `foo` workspace member `a/b` continues to use the workspace-level .venv/uv.lock as it did for the first-level workspace member `a`.

`uv sync -v --all-packages` from within the `foo/a` folder:
```
DEBUG uv 0.9.7 (Homebrew 2025-10-30)
DEBUG Acquired shared lock for `/Users/stewartadam/.cache/uv`
DEBUG Found project root: `/Users/stewartadam/foo/a`
DEBUG Found workspace root: `/Users/stewartadam/foo`
DEBUG Adding root workspace member: `/Users/stewartadam/foo`
DEBUG Adding discovered workspace member: `/Users/stewartadam/foo/a`
DEBUG Adding discovered workspace member: `/Users/stewartadam/foo/a/b`
DEBUG Acquired lock for `/Users/stewartadam/foo`
DEBUG Reading Python requests from version file at `/Users/stewartadam/foo/.python-version`
DEBUG Using Python request `3.12` from version file at `/Users/stewartadam/foo/.python-version`
DEBUG Checking for Python environment at: `/Users/stewartadam/foo/.venv`
DEBUG The project environment's Python version satisfies the request: `Python 3.12`
DEBUG Released lock at `/var/folders/1m/xxn68ngs7bb6h6x6bt442tth0000gn/T/uv-d4d39f85f2047a7c.lock`
DEBUG Acquired lock for `/Users/stewartadam/foo/.venv`
DEBUG Using request timeout of 30s
DEBUG Found static `pyproject.toml` for: a @ file:///Users/stewartadam/foo/a
DEBUG Found workspace root: `/Users/stewartadam/foo`
DEBUG Found static `pyproject.toml` for: b @ file:///Users/stewartadam/foo/a/b
DEBUG Project is contained in non-workspace project: `/Users/stewartadam/foo/a`
DEBUG No workspace root found, using project root
DEBUG Found static `pyproject.toml` for: foo @ file:///Users/stewartadam/foo
DEBUG Found workspace root: `/Users/stewartadam/foo`
DEBUG Existing `uv.lock` satisfies workspace requirements
Resolved 3 packages in 5ms
DEBUG Using request timeout of 30s
Audited in 0.00ms
DEBUG Released lock at `/Users/stewartadam/foo/.venv/.lock`
DEBUG Released lock at `/Users/stewartadam/.cache/uv/.lock`
```

`uv sync -v --all-packages` from within the `foo/a/b` folder:
```
DEBUG uv 0.9.7 (Homebrew 2025-10-30)
DEBUG Acquired shared lock for `/Users/stewartadam/.cache/uv`
DEBUG Found project root: `/Users/stewartadam/foo/a/b`
DEBUG Project is contained in non-workspace project: `/Users/stewartadam/foo/a`
DEBUG No workspace root found, using project root
DEBUG Acquired lock for `/Users/stewartadam/foo/a/b`
DEBUG No Python version file found in workspace: /Users/stewartadam/foo/a/b
DEBUG Using Python request `>=3.12` from `requires-python` metadata
DEBUG Checking for Python environment at: `.venv`
DEBUG The project environment's Python version satisfies the request: `Python >=3.12`
DEBUG Released lock at `/var/folders/1m/xxn68ngs7bb6h6x6bt442tth0000gn/T/uv-38125e2740c2addc.lock`
DEBUG Acquired lock for `.venv`
DEBUG Using request timeout of 30s
DEBUG Found static `pyproject.toml` for: b @ file:///Users/stewartadam/foo/a/b
DEBUG Project is contained in non-workspace project: `/Users/stewartadam/foo/a`
DEBUG No workspace root found, using project root
DEBUG Existing `uv.lock` satisfies workspace requirements
Resolved 1 package in 3ms
DEBUG Using request timeout of 30s
Audited in 0.00ms
DEBUG Released lock at `/Users/stewartadam/foo/a/b/.venv/.lock`
DEBUG Released lock at `/Users/stewartadam/.cache/uv/.lock`
```

### Platform

MacOS Tahoe

### Version

uv 0.9.7 (Homebrew 2025-10-30)

### Python version

Python 3.12.12

Contributor guide

Open the contributing guide

Research direction

Reproduce the nested workspace behavior with the documented uv init and uv sync commands, especially uv sync -v --all-packages from foo/a and foo/a/b. Trace the workspace-root discovery shown in the logs and verify that syncing from a/b uses foo/.venv and foo/uv.lock rather than creating local files. Done means nested members consistently resolve to the outer workspace.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, rust
Domain
build-system, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.