Skip to content

Access Denied error in Windows when removing .exe files from .venv #11134

@nathanjmcdougall

Description

@nathanjmcdougall

Summary

Example Error Message

PS C:\Users\namc\Temp\permissionsissue> uv remove ruff
Resolved 1 package in 8ms
error: failed to remove file `C:\Users\namc\Temp\permissionsissue\.venv\Lib\site-packages\..\..\Scripts\ruff.exe`: Access is denied. (os error 5)

Overview of the issue

On Windows, a uv managed environment will try to delete .exe files in .venv/Scripts. However, these might be running via some external process, creating a permissions error, and preventing deletion.

This is especially an issue with the uv remove command. First, the lockfile is updated, then uv will attempt to delete .exe files and encounter an error. This would leave the .venv and lockfile out-of-sync. This means all subsequent calls involving syncing will give a permissions error too, e.g. uv sync, uv add numpy, etc. From the user's perspective they are somewhat stuck.

A Specific Example

Trying to remove Ruff with uv can lead to a permissions issue when using the VS Code Ruff extension on Windows, since uv is trying to delete .venv/Scripts/ruff.exe while the Ruff Language Server is still using it. I suspect this is the root cause of #7382.

Compared behaviour with pip

The same permissions error occurs when running uv pip uninstall ruff rather than uv remove. However, pip itself can cope with this situation: pip uninstall ruff will move the executable into a temporary directory. It warns the user that it can be deleted manually, giving the temp dir path:

WARNING: Failed to remove contents in a temporary directory 'C:\Users\namc\AppData\Local\Temp\pip-uninstall-lvja8bs4'.
You can safely remove it manually.

I reckon this is a great solution - it keeps the .venv properly synced while still letting the process continue.

In the specific case I mentioned before, the Language Server can keep running (or perhaps the VS Code extension identify that the exe has moved and restart it in an isolated environment), but in any case, the uv remove ruff command would run successfully.

Steps to reproduce:

  1. Ensure VS Code is installed with the charliermarsh.ruff extension.
  2. Open an empty directory in VS Code, and run the following commands from Powershell within VS Code:
  3. uv init
  4. uv add ruff
  5. In VS Code: View > Command Palette > Developer: Reload Window
  6. code hello.py
  7. In VS Code: View > Output > Ruff Language Server. Wait until the first INFO message appears to show the server has started.
  8. uv remove ruff should reproduce the error.

Whereas at step 7, there is a workaround via pip which only gives a warning and not an error:

uv add --dev pip
uv run pip uninstall ruff
uv remove ruff pip

I'm sorry if this is a bit clunky, unfortunately I tried to reproduce this without VS Code but it's beyond my expertise.

Notes

The point of step 5 is to open a Python file, which seems to help to trigger the Ruff language server to start.
While the extensions start up after the reload in step 4, it may take a minute for the Ruff language server to be available on the Output menu.

An example message for step 6 is;

INFO main ruff_server::session::index: Registering workspace: c:\Users\namc\Temp\permissionsissue

VS Code Version information

Version: 1.96.4 (user setup)
Commit: cd4ee3b1c348a13bafd8f9ad8060705f6d4b9cba
Date: 2025-01-16T00:16:19.038Z
Electron: 32.2.6
ElectronBuildId: 10629634
Chromium: 128.0.6613.186
Node.js: 20.18.1
V8: 12.8.374.38-electron.0
OS: Windows_NT x64 10.0.19045

Identifier charliermarsh.ruff
Version 2025.4.0
Last Updated 2025-01-28, 10:14:12

Platform

Windows 10 x86-64

Version

uv 0.5.21 (3478c06 2025-01-17)

Python version

Python 3.11.6

Metadata

Metadata

Assignees

Labels

needs-decisionUndecided if this should be donewindowsSpecific to the Windows platform

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions