pypa/pip · error · ValueError
path ' ' cannot be absolute
Error message
path '%s' cannot be absolute
What it means
Raised as ValueError by distlib.util.convert_path when, on a non-Unix system (os.sep != '/', i.e. Windows), the supplied pathname starts with '/'. convert_path translates Unix-style '/' separators in setup-script filenames to the native separator; an absolute leading slash is rejected because setup filenames are expected to be relative. On POSIX (os.sep == '/') the function is a no-op and never raises.
Solutions
- Pass relative paths only; strip any leading '/' (and drive letters) before calling convert_path.
- Guard with: if os.name != 'nt' or not pathname.startswith('/'): before converting.
- Build resource paths with os.path.join of relative components instead of hard-coding slashes.
Example fix
# before
convert_path('/data/templates/index.html')
# after
convert_path('data/templates/index.html') Defensive patterns
Strategy: validation
Validate before calling
def safe_convert_path(pathname):
if os.sep != '/' and pathname.startswith('/'):
pathname = pathname.lstrip('/')
return convert_path(pathname) Type guard
def is_relative_unix_path(s: str) -> bool:
return isinstance(s, str) and not s.startswith('/') Try / catch
try:
convert_path(pathname)
except ValueError as e:
if 'cannot be absolute' in str(e):
convert_path(pathname.lstrip('/')) Prevention
- Only pass relative paths to convert_path.
- Build paths with os.path.join of relative components.
When it happens
Trigger: Calling convert_path('/abs/path/to/file') on Windows; setup.py data_files or package_data entries containing absolute Unix paths; cross-platform packaging code that passes platform-absolute paths to convert_path on Windows.
Common situations: Building wheels/sdists on Windows where a resource path was constructed with a leading '/'; config files supplying absolute paths into a packaging pipeline that calls convert_path.
Related errors
- path ' ' cannot end with '/
- 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/c749583ea2094256.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/distlib/util.py:474
return value
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()
View on GitHub (pinned to f399c37189)