pypa/pip · error · ValueError
Unknown CSIDL name: {csidl_name}
Error message
Unknown CSIDL name: {csidl_name} What it means
Raised as ValueError by get_win_folder_from_env_vars when the requested csidl_name is neither handled by get_win_folder_if_csidl_name_not_env_var nor present in the {CSIDL_APPDATA, CSIDL_COMMON_APPDATA, CSIDL_LOCAL_APPDATA} env-var mapping. The message echoes the unknown CSIDL constant.
Source
Thrown at src/pip/_vendor/platformdirs/windows.py:208
def site_runtime_dir(self) -> str:
"""Runtime directory shared by users, same as `user_runtime_dir`."""
return self.user_runtime_dir
def get_win_folder_from_env_vars(csidl_name: str) -> str:
"""Get folder from environment variables."""
result = get_win_folder_if_csidl_name_not_env_var(csidl_name)
if result is not None:
return result
env_var_name = {
"CSIDL_APPDATA": "APPDATA",
"CSIDL_COMMON_APPDATA": "ALLUSERSPROFILE",
"CSIDL_LOCAL_APPDATA": "LOCALAPPDATA",
}.get(csidl_name)
if env_var_name is None:
msg = f"Unknown CSIDL name: {csidl_name}"
raise ValueError(msg)
result = os.environ.get(env_var_name)
if result is None:
msg = f"Unset environment variable: {env_var_name}"
raise ValueError(msg)
return result
def get_win_folder_if_csidl_name_not_env_var(csidl_name: str) -> str | None: # ruff:ignore[too-many-return-statements]
"""Get a folder for a CSIDL name that does not exist as an environment variable."""
if csidl_name == "CSIDL_PERSONAL":
return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Documents") # ruff:ignore[os-path-join]
if csidl_name == "CSIDL_DOWNLOADS":
return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Downloads") # ruff:ignore[os-path-join]
if csidl_name == "CSIDL_MYPICTURES":
return os.path.join(os.path.normpath(os.environ["USERPROFILE"]), "Pictures") # ruff:ignore[os-path-join]
View on GitHub (pinned to d7d0d0a394)
Solutions
- Pass one of the supported CSIDL constants: CSIDL_APPDATA, CSIDL_COMMON_APPDATA, CSIDL_LOCAL_APPDATA (or the not-env-var ones like CSIDL_PERSONAL).
- Avoid calling the internal get_win_folder_from_env_vars directly; use the public Windows()/platformdirs API which only emits valid constants.
- Correct the typo in any WIN_PD_OVERRIDE_* environment variable name.
Example fix
# before
get_win_folder_from_env_vars('CSIDL_Dekstop') # ValueError
# after
get_win_folder_from_env_vars('CSIDL_LOCAL_APPDATA') Defensive patterns
Strategy: validation
Validate before calling
KNOWN = {'CSIDL_APPDATA', 'CSIDL_COMMON_APPDATA', 'CSIDL_LOCAL_APPDATA',
'CSIDL_PERSONAL', 'CSIDL_DOWNLOADS', 'CSIDL_MYPICTURES',
'CSIDL_MYVIDEO', 'CSIDL_MYMUSIC', 'CSIDL_PROGRAMS', 'CSIDL_COMMON_PROGRAMS'}
if csidl_name in KNOWN:
get_win_folder_from_env_vars(csidl_name) Type guard
def is_known_csidl(name: str) -> bool:
return name in {'CSIDL_APPDATA','CSIDL_COMMON_APPDATA','CSIDL_LOCAL_APPDATA',
'CSIDL_PERSONAL','CSIDL_DOWNLOADS','CSIDL_MYPICTURES',
'CSIDL_MYVIDEO','CSIDL_MYMUSIC','CSIDL_PROGRAMS','CSIDL_COMMON_PROGRAMS'} Try / catch
try:
p = get_win_folder_from_env_vars(name)
except ValueError as e:
if 'Unknown CSIDL name' in str(e):
# name is unsupported; use a default
...
raise Prevention
- Use the public platformdirs API rather than internal CSIDL helpers.
- Whitelist CSIDL constants in your own code.
When it happens
Trigger: Calling get_win_folder_from_env_vars(csidl_name) with a CSIDL constant not in the supported set (e.g. a typo like 'CSIDL_Dekstop' or an unsupported constant). This path is selected when neither ctypes nor winreg is available.
Common situations: A user override or custom code passing a wrong CSIDL name; running under a stripped-down Windows-like environment (no ctypes/winreg) so the env-var fallback path is used with an invalid name.
Related errors
- SHGetKnownFolderPath returned NULL for {csidl_name}
- should only be used on Unix
- Unset environment variable: {env_var_name}
- Could not find adapter for {registry} and {ob}
- Fatal Internal error [id=2]. Please report as a bug.
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/866fabc2db4fa203.json.
Report an issue: GitHub.