pypa/pip · error · ValueError
SHGetKnownFolderPath returned NULL for
Error message
SHGetKnownFolderPath returned NULL for {csidl_name} What it means
Raised after the ctypes resolver calls shell32.SHGetKnownFolderPath for a known GUID and the returned pointer is NULL. A NULL result means Windows itself could not resolve the folder, even though the GUID was valid. This typically indicates the folder is not registered, not present on the current system, or the user profile is incomplete.
Solutions
- Verify the user profile is complete (sign out/in or run 'systempropertiesadvanced' to rebuild profile folders).
- Run under an interactive user account rather than SYSTEM/LocalService where the known folder may be absent.
- Pre-create or redirect the missing known folder via the registry or Group Policy.
- Fall back to an adjacent folder (e.g. LOCALAPPDATA) if the specific folder is optional to your logic.
Example fix
try:
folder = get_win_folder_via_ctypes('CSIDL_DOWNLOADS')
except ValueError:
folder = os.path.join(os.environ['USERPROFILE'], 'Downloads') Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
null
Try / catch
try:
folder = get_win_folder_via_ctypes(name)
except ValueError as e:
if 'NULL' in str(e):
folder = os.path.join(os.environ.get('USERPROFILE',''), 'Downloads')
else:
raise Prevention
- Run under a profile that has the known folder materialized.
- Provide a fallback path for environments like containers/Server Core where folders may be absent.
When it happens
Trigger: SHGetKnownFolderPath returns a NULL LPWSTR (path_ptr.value is None) at windows.py:358-362, e.g. requesting CSIDL_COMMON_PROGRAMS in a stripped-down Windows environment, a corrupted user profile, or running under a service account whose profile lacks the folder.
Common situations: Running pip/platformdirs in a container, Windows Server Core, or a locked-down account where the Downloads/Pictures folder is not materialized; redirected/roamed folders that failed to provision; a broken user profile after a migration.
Related errors
- Unknown CSIDL name
- cannot read
- error when loading custom formatter
- excclass option is not an exception class
- filter not found
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/056b9b54b246cadf.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/platformdirs/windows.py:363
kernel32.GetShortPathNameW.argtypes = [wintypes.LPWSTR, wintypes.LPWSTR, wintypes.DWORD]
def resolve(csidl_name: str) -> str:
folder_guid = _KNOWN_FOLDER_GUIDS.get(csidl_name)
if folder_guid is None:
msg = f"Unknown CSIDL name: {csidl_name}"
raise ValueError(msg)
guid = _GUID()
ole32.CLSIDFromString(folder_guid, byref(guid))
path_ptr = wintypes.LPWSTR()
shell32.SHGetKnownFolderPath(byref(guid), _KF_FLAG_DONT_VERIFY, None, byref(path_ptr))
result = path_ptr.value
ole32.CoTaskMemFree(path_ptr)
if result is None:
msg = f"SHGetKnownFolderPath returned NULL for {csidl_name}"
raise ValueError(msg)
if any(ord(c) > 255 for c in result): # ruff:ignore[magic-value-comparison]
buf = create_unicode_buffer(1024)
if kernel32.GetShortPathNameW(result, buf, 1024):
result = buf.value
return result
return resolve
def get_win_folder_via_ctypes(csidl_name: str) -> str:
"""Get folder via :func:`SHGetKnownFolderPath`.
See https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath.
"""
return _build_get_win_folder_via_ctypes()(csidl_name)View on GitHub (pinned to f399c37189)