Skip to content

uv lock errors if .venv is not valid #19832

Description

@tylerh111

Summary

When .venv folder exists, not empty, and not considered a virtual environment by uv, uv lock will fail to find a suitable python executable to use and raise an error.

I have the following folder structure for managing multiple virtual environments of different python versions for a specific project. They are all created from uv venv -p <version> ".venv/<version>" Directory structure below.

.venv/
|-- 3.10/
|-- 3.11/
|-- 3.12/
|-- 3.13/
|-- 3.14/

When running uv lock, it (for some reason) check explicitly if the folder .venv is a virtual environment (basically to find a suitable python executable). I get the following error (note the path is an absolute path to .venv which I replaced with .).

error: Project virtual environment directory `./.venv` cannot be used because it is not a valid Python environment (no Python executable was found)

This doesn't work for my setup because .venv is not a virtual environment. The work around is having to rename the folder temporarily to allow uv lock to run successfully.

Since this can work without a virtual environment at all, uv lock should fallback to either the global python or a managed python instance that's currently installed. Alternatively, an flag similar to --active could be implemented so that uv lock uses that virtual environment instead.

To summarize, if .venv folder exists and is not empty and is not a complete virtual environment, uv lock will fail. The following is a example to setup this situation.

mkdir example
cd example

mkdir .venv
touch .venv/bad

echo > pyproject.toml << EOF
[project]
name = "example"
version = "0"
requires-python = ">=3"
EOF

uv lock
#> error: Project virtual environment directory `.../example/.venv` cannot be used ...

Platform

Linux 7.0.11-arch1-1 x86_64 GNU/Linux

Version

uv 0.11.19 (7b2cff1 2026-06-03 x86_64-unknown-linux-gnu)

Python version

No response

Activity

  1. tylerh111 commented on Jun 13, 2026

    @tylerh111
    Author

    Tracing through the code, the error is produced from handling a uv_python::Error::InvalidEnvironment caused by PythonEnvironment::from_root.

    Err(uv_python::Error::InvalidEnvironment(inner)) => {
    // If there's an invalid environment with existing content, we error instead of
    // deleting it later on
    match inner.kind {
    InvalidEnvironmentKind::NotDirectory => {
    return Err(ProjectError::InvalidProjectEnvironmentDir(
    root,
    inner.kind.to_string(),
    ));
    }
    InvalidEnvironmentKind::MissingExecutable(_) => {
    // If it's not an empty directory
    if fs_err::read_dir(&root).is_ok_and(|mut dir| dir.next().is_some()) {
    // ... and there's no `pyvenv.cfg`
    if !root.join("pyvenv.cfg").try_exists().unwrap_or_default() {
    // ... then it's not a valid Python environment
    return Err(ProjectError::InvalidProjectEnvironmentDir(
    root,
    "it is not a valid Python environment (no Python executable was found)"
    .to_string(),
    ));
    }
    }
    // Otherwise, we'll delete it
    }
    // If the environment is an empty directory, it's fine to use
    InvalidEnvironmentKind::Empty => {}
    }
    }

    We could just treat that error the same as a missing environment since they are both unusable and since root (the path to the venv) is not used afterwards the PythonEnvironment::from_root call. This way, discovery basically falls back to PythonInstallation::find_or_download(...).

  2. changed the title [-]`uv lock` errors if `.venv` is not a virtual environment[/-] [+]`uv lock` errors if `.venv` is not valid[/+] on Jun 13, 2026
  3. added a commit that references this issue on Aug 12, 2026
  4. added a commit that references this issue on Aug 12, 2026
    eef91cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions