{"id":"056b9b54b246cadf","repo":"pypa/pip","slug":"shgetknownfolderpath-returned-null-for-csidl-name","errorCode":null,"errorMessage":"SHGetKnownFolderPath returned NULL for {csidl_name}","messagePattern":"SHGetKnownFolderPath returned NULL for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/platformdirs/windows.py","lineNumber":363,"sourceCode":"    kernel32.GetShortPathNameW.argtypes = [wintypes.LPWSTR, wintypes.LPWSTR, wintypes.DWORD]\n\n    def resolve(csidl_name: str) -> str:\n        folder_guid = _KNOWN_FOLDER_GUIDS.get(csidl_name)\n        if folder_guid is None:\n            msg = f\"Unknown CSIDL name: {csidl_name}\"\n            raise ValueError(msg)\n\n        guid = _GUID()\n        ole32.CLSIDFromString(folder_guid, byref(guid))\n\n        path_ptr = wintypes.LPWSTR()\n        shell32.SHGetKnownFolderPath(byref(guid), _KF_FLAG_DONT_VERIFY, None, byref(path_ptr))\n        result = path_ptr.value\n        ole32.CoTaskMemFree(path_ptr)\n\n        if result is None:\n            msg = f\"SHGetKnownFolderPath returned NULL for {csidl_name}\"\n            raise ValueError(msg)\n\n        if any(ord(c) > 255 for c in result):  # ruff:ignore[magic-value-comparison]\n            buf = create_unicode_buffer(1024)\n            if kernel32.GetShortPathNameW(result, buf, 1024):\n                result = buf.value\n\n        return result\n\n    return resolve\n\n\ndef get_win_folder_via_ctypes(csidl_name: str) -> str:\n    \"\"\"Get folder via :func:`SHGetKnownFolderPath`.\n\n    See https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath.\n\n    \"\"\"\n    return _build_get_win_folder_via_ctypes()(csidl_name)","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/platformdirs/windows.py#L345-L381","documentation":"Raised as ValueError by the ctypes resolve() when the Windows SHGetKnownFolderPath API call returned a NULL pointer for the given CSIDL/known-folder GUID. A NULL result means the system could not resolve that known folder (e.g. it does not exist on this Windows edition or the user profile lacks it).","triggerScenarios":"resolve(csidl_name) calls shell32.SHGetKnownFolderPath with the folder GUID; path_ptr.value comes back None, so the folder path is unavailable on the running Windows system.","commonSituations":"Server Core or a stripped Windows SKU that does not provide a particular known folder, a corrupted/missing user profile (e.g. Downloads not materialized), or a service account without a populated profile.","solutions":["Set the corresponding WIN_PD_OVERRIDE_<NAME> environment variable to a concrete path so platformdirs skips the API call.","Run under an interactive user account whose profile has the folder materialized.","Wrap the call in try/except ValueError and fall back to a sensible default path."],"exampleFix":"# before\npath = get_win_folder('CSIDL_DOWNLOADS')  # NULL -> ValueError\n\n# after\ntry:\n    path = get_win_folder('CSIDL_DOWNLOADS')\nexcept ValueError:\n    path = os.path.join(os.environ['USERPROFILE'], 'Downloads')","handlingStrategy":"fallback","validationCode":"null","typeGuard":"null","tryCatchPattern":"try:\n    path = get_win_folder(csidl_name)\nexcept ValueError as e:\n    if 'SHGetKnownFolderPath returned NULL' in str(e):\n        path = os.path.join(os.environ.get('USERPROFILE',''), default_subdir(csidl_name))\n    raise","preventionTips":["Set WIN_PD_OVERRIDE_<NAME> for known folders missing on Server Core/service accounts.","Provide a fallback path for known folders that may be unavailable."],"tags":["python","platformdirs","windows","csidl","winapi"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}