Skip to content

Conversation

@SabriRamadanTNG
Copy link
Contributor

@SabriRamadanTNG SabriRamadanTNG commented Dec 11, 2025

In bin/pyenv-virtualenv-delete there is a code block at the bottom that runs rm -rf on variable PREFIX if the variable PREFIX is set.
Now here lays a serious bug: if the script itself did not set this variable beforehand, any other path stored in PREFIX will be deleted. I observe this happening when executing with the force -f flag and the provided env doesn't exist. The case where a PREFIX var is already set seems to specifically happen on macOS in combination with yarn and pyenv-virtualenv both installed via Homebrew. When pyenv-virtualenv is ran via a yarn command, for example yarn recreate-setup with recreate-setup invoking pyenv-virtualenv-delete, e.g.

"recreate-setup": "pyenv virtualenv-delete -f non-existent-venv",

there is a PREFIX env variable set to /opt/homebrew. I'm not sure which application involved here sets this variable.

The result is that it will try to ❗DELETE EVERYTHING ❗in /opt/homebrew therefore nuking the entire homebrew setup of the user.

This PR provides a first quick workaround by renaming the variable to a very specific one such that it should not come to naming conflicts. Presumably a proper fix of the underlying code flow should be evaluated.

…applications

* if set, there is potentially catastrophic loss of data due to the "rm -rf" command being executed on it
@SabriRamadanTNG SabriRamadanTNG force-pushed the prevent-deletion-of-contents-in-generic-prefix-env-var branch from e900512 to 7a45c55 Compare December 11, 2025 10:17
Copy link
Member

@native-api native-api left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The standard practice in Bash for such cases is to either initialize or unset variables that might've been already set elsewhere, before they are first used.

It won't hurt to change the name to be more descriptive, either. But the PYENV prefix for an internal non-environment variable is redundant.

@SabriRamadanTNG
Copy link
Contributor Author

The standard practice in Bash for such cases is to either initialize or unset variables that might've been already set elsewhere, before they are first used.

It won't hurt to change the name to be more descriptive, either. But the PYENV prefix for an internal non-environment variable is redundant.

Sounds reasonable to me, so then I will do a small rewrite with the following:

  • rename variable again without the PYENV prefix, any suggestion?
  • unset variable at start of the script

Feel free to take this over if you prefer, for me fixing this is the priority as in our specific project setup it has caused some real headaches and loss of time due to having to restore (Homebrew) backups.

@native-api
Copy link
Member

native-api commented Dec 11, 2025

Feel free to take this over if you prefer, for me fixing this is the priority as in our specific project setup it has caused some real headaches and loss of time due to having to restore (Homebrew) backups.

You can already use this branch for a quick fix.

Before this gets merged, we need to sort out the test failure, and one more thing.

By the script logic, PREFIX (now ENV_PREFIX) is not supposed to be unset by the time it's checked.
What are your circumstances that caused it to be so?

E.,g. could you provide the debug trace of its execution (on a test system) as per the issue template that reproduces the problem?

@native-api
Copy link
Member

native-api commented Dec 11, 2025

Feel free to take this over if you prefer

At the moment, I cannot invest enough time to see this to completion but I should be able to within a day or two.

But I do very much need the aforementioned debug trace to identify and fix the root cause.

@SabriRamadanTNG
Copy link
Contributor Author

Thank you for addressing this so quickly.

At the moment people on the project are aware of this issue so a couple of days should not make any difference.
I will try to provide the debug trace tomorrow.

At the moment here is how I was able to reproduce it:

  • have the PREFIX variable set in the shell environment (for us this is done via the specific circumstances mentioned above)
  • run pyenv virtualenv-delete -f non-existent-venv
    • it is important the the environment does not exist
    • it is important that the -f flag is set
  • the script will run through to the block at the bottom without setting PREFIX
  • since PREFIX has been set externally, the check for it passes and it will run rm -rf on its value

@SabriRamadanTNG
Copy link
Contributor Author

Here is the debug trace.

pyenv_debug_trace.txt

Notice how at the end, it says

rm: /opt/homebrew: Permission denied

which just means it does not have permissions to delete the homebrew folder itself, but everything inside it is gone.
The obvious indicator is the last line

pyenv:8: command not found: pyenv

@SabriRamadanTNG
Copy link
Contributor Author

Tests are passing for me locally, on macOS 26.1 with bats/bin/bats --tap test.

@native-api
Copy link
Member

sort out the test failure

Diagnosed it. It's caused by a race condition in the stub test helper when 2 of them run simultaneously.
It's unrelated to the current PR -- so I'll fix it separately.

identify and fix the root cause

It's the fact that the logic doesn't bail out with -f when it's detected that the env doesn't exist.
It also uses ENV_PREFIX as an indicator that it has been found -- so we do need to initialize it.

@native-api native-api changed the title Prevent catastrophic loss of data if PREFIX env variable is (not) set Prevent loss of data on virtualenv-delete -f if the env doesn't exist and the PREFIX envvar is set elsewhere Dec 13, 2025
@native-api native-api merged commit 6423361 into pyenv:master Dec 13, 2025
5 checks passed
@SabriRamadanTNG
Copy link
Contributor Author

Just wanted to say thank you for reacting so quickly and helping to debug and fix the issue. Highly appreciated.
Cheers.

@SabriRamadanTNG SabriRamadanTNG deleted the prevent-deletion-of-contents-in-generic-prefix-env-var branch December 14, 2025 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants