pypa/pip · error · ValueError
path ' ' cannot end with '/
Error message
path '%s' cannot end with '/'
What it means
Raised as ValueError by distlib.util.convert_path on non-Unix systems when the pathname ends with '/'. A trailing slash denotes a directory, which convert_path rejects because it is meant for file-name translation in setup scripts, not directory specifiers. Like the absolute-path check, it only fires when os.sep != '/' (Windows).
Solutions
- Strip trailing '/' before calling: pathname = pathname.rstrip('/').
- Validate with: assert not pathname.endswith('/') on Windows before convert_path.
- Construct paths from explicit components rather than string concatenation that can leave a dangling slash.
Example fix
# before
convert_path('pkg/resources/')
# after
convert_path('pkg/resources') Defensive patterns
Strategy: validation
Validate before calling
def safe_convert_path(pathname):
if pathname.endswith('/'):
pathname = pathname.rstrip('/')
return convert_path(pathname) Type guard
def has_no_trailing_slash(s: str) -> bool:
return isinstance(s, str) and (not s or not s.endswith('/')) Try / catch
try:
convert_path(pathname)
except ValueError as e:
if 'cannot end' in str(e):
convert_path(pathname.rstrip('/')) Prevention
- rstrip('/') on user path input.
- Avoid joining with an empty trailing component.
When it happens
Trigger: Calling convert_path('pkg/data/') on Windows; setup.py package_data or scripts entries that accidentally include a trailing slash; normalizing user-supplied path strings that end with '/' on Windows.
Common situations: Trailing slashes left over from os.path.join with an empty final component; copy-pasted directory paths from Unix examples used in packaging config on Windows.
Related errors
- path ' ' cannot be absolute
- file '%r' does not exist
- invalid glob %r: mismatching set marker
- invalid glob %r: recursive glob "**" must be used alone
- which would be overwritten
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/ebe56e225dba2514.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/distlib/util.py:476
def convert_path(pathname):
"""Return 'pathname' as a name that will work on the native filesystem.
The path is split on '/' and put back together again using the current
directory separator. Needed because filenames in the setup script are
always supplied in Unix style, and have to be converted to the local
convention before we can actually use them in the filesystem. Raises
ValueError on non-Unix-ish systems if 'pathname' either starts or
ends with a slash.
"""
if os.sep == '/':
return pathname
if not pathname:
return pathname
if pathname[0] == '/':
raise ValueError("path '%s' cannot be absolute" % pathname)
if pathname[-1] == '/':
raise ValueError("path '%s' cannot end with '/'" % pathname)
paths = pathname.split('/')
while os.curdir in paths:
paths.remove(os.curdir)
if not paths:
return os.curdir
return os.path.join(*paths)
class FileOperator(object):
def __init__(self, dry_run=False):
self.dry_run = dry_run
self.ensured = set()
self._init_record()
def _init_record(self):
self.record = FalseView on GitHub (pinned to f399c37189)