pypa/pip · error · BadCommand
Cannot find command - invalid PATH
Error message
Cannot find command {cls.name!r} - invalid PATH What it means
Raised by VersionControl.run_command() when the OS raises NotADirectoryError while trying to execute the VCS binary (git, svn, hg, bzr). This means the PATH contains an entry that is a file rather than a directory, causing the executable lookup to fail in an unexpected way. It is wrapped as a BadCommand.
Solutions
- Print your PATH and verify every entry is a directory: 'echo $PATH | tr ':' "\n" | xargs -I{} test -d {} && echo OK || echo BAD: {}'
- Fix the PATH in your shell profile / Dockerfile so it contains only directory paths
- Ensure the VCS binary (e.g. git) is installed: 'which git' and 'git --version'
- If the VCS tool is missing, install it (e.g. 'apt-get install git')
Example fix
// before # PATH contains '/usr/bin/git' (a file) instead of '/usr/bin' export PATH="/usr/bin/git:/usr/local/bin:$PATH" pip install git+https://example.com/repo.git // after export PATH="/usr/bin:/usr/local/bin:$PATH" pip install git+https://example.com/repo.git
Defensive patterns
Strategy: validation
Validate before calling
import os, shutil
def vcs_command_is_available(name: str) -> bool:
if not shutil.which(name):
return False
# verify PATH entries are directories
for entry in os.environ.get('PATH', '').split(os.pathsep):
if entry and not os.path.isdir(entry):
return False # a PATH entry is not a directory
return True
# before a VCS-based install
if not vcs_command_is_available('git'):
raise EnvironmentError('git not found or PATH is malformed') Type guard
import os
def path_entries_are_directories() -> bool:
return all(os.path.isdir(e) for e in os.environ.get('PATH', '').split(os.pathsep) if e) Try / catch
from pip._internal.exceptions import BadCommand
try:
vc.run_command(['version'])
except BadCommand as e:
if 'invalid PATH' in str(e):
raise EnvironmentError(f'fix PATH to contain only directories: {e}')
if 'do you have' in str(e):
raise EnvironmentError(f'install the VCS tool: {e}')
raise Prevention
- Ensure every PATH entry is a directory, never a file path
- Install the required VCS binary (git, svn, hg) and verify with 'which <name>'
- Validate PATH in shell profiles and Dockerfiles
- Use absolute directory paths in PATH, not binary paths
When it happens
Trigger: Calling run_command() where the subprocess spawn raises NotADirectoryError — typically because a PATH component is a regular file (e.g. '/usr/bin/git' accidentally listed in PATH instead of '/usr/bin'). The exception is caught at line 650 and re-raised as BadCommand.
Common situations: A malformed PATH environment variable with a file path instead of directory paths. A PATH entry like '/usr/local/bin/git' (pointing at the binary) rather than '/usr/local/bin'. A broken virtualenv or shell profile that corrupted PATH. A Docker image with an incorrectly set PATH.
Related errors
- unexpected show-ref line
- {url}
- Badly formatted data
- Can not perform a '--user' install. User site-packages are…
- Can not perform a '--user' install. User site-packages are…
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/af5c0b8f9689a3a5.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/vcs/versioncontrol.py:651
cmd = make_command(cls.name, *cmd)
if command_desc is None:
command_desc = format_command_args(cmd)
try:
return call_subprocess(
cmd,
show_stdout,
cwd,
on_returncode=on_returncode,
extra_ok_returncodes=extra_ok_returncodes,
command_desc=command_desc,
extra_environ=extra_environ,
unset_environ=cls.unset_environ,
spinner=spinner,
log_failed_cmd=log_failed_cmd,
stdout_only=stdout_only,
)
except NotADirectoryError:
raise BadCommand(f"Cannot find command {cls.name!r} - invalid PATH")
except FileNotFoundError:
# errno.ENOENT = no such file or directory
# In other words, the VCS executable isn't available
raise BadCommand(
f"Cannot find command {cls.name!r} - do you have "
f"{cls.name!r} installed and in your PATH?"
)
except PermissionError:
# errno.EACCES = Permission denied
# This error occurs, for instance, when the command is installed
# only for another user. So, the current user don't have
# permission to call the other user command.
raise BadCommand(
f"No permission to execute {cls.name!r} - install it "
f"locally, globally (ask admin), or check your PATH. "
f"See possible solutions at "
f"https://pip.pypa.io/en/latest/reference/pip_freeze/"
f"#fixing-permission-denied."View on GitHub (pinned to f399c37189)