{"record":{"id":"8d5531f7d0467f6c","repo":"Flow-Launcher/Flow.Launcher","slug":"failed-to-parse-file-path","errorCode":null,"errorMessage":"Failed to parse file path","messagePattern":"Failed to parse file path","errorType":"exception","errorClass":"COMException","httpStatus":null,"severity":"warning","filePath":"Flow.Launcher.Infrastructure/Win32Helper.cs","lineNumber":874,"sourceCode":"\n        #region Explorer\n\n        // https://learn.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shopenfolderandselectitems\n\n        public static unsafe void OpenFolderAndSelectFile(string filePath)\n        {\n            ITEMIDLIST* pidlFolder = null;\n            ITEMIDLIST* pidlFile = null;\n\n            var folderPath = Path.GetDirectoryName(filePath);\n\n            try\n            {\n                var hrFolder = PInvoke.SHParseDisplayName(folderPath, null, out pidlFolder, 0, out _);\n                if (hrFolder.Failed) throw new COMException(\"Failed to parse folder path\", hrFolder);\n\n                var hrFile = PInvoke.SHParseDisplayName(filePath, null, out pidlFile, 0, out _);\n                if (hrFile.Failed) throw new COMException(\"Failed to parse file path\", hrFile);\n\n                var hrSelect = PInvoke.SHOpenFolderAndSelectItems(pidlFolder, 1, &pidlFile, 0);\n                if (hrSelect.Failed) throw new COMException(\"Failed to open folder and select item\", hrSelect);\n            }\n            finally\n            {\n                if (pidlFile != null) PInvoke.CoTaskMemFree(pidlFile);\n                if (pidlFolder != null) PInvoke.CoTaskMemFree(pidlFolder);\n            }\n        }\n\n        #endregion\n\n        #region Win32 Dark Mode\n\n        /*\n         * Inspired by https://github.com/ysc3839/win32-darkmode\n         */","sourceCodeStart":856,"sourceCodeEnd":892,"githubUrl":"https://github.com/Flow-Launcher/Flow.Launcher/blob/7fc63b07bbaa10a0f0b2601487913fcba9ed24b0/Flow.Launcher.Infrastructure/Win32Helper.cs#L856-L892","documentation":"Thrown as COMException carrying the file-parsing HRESULT when SHParseDisplayName(filePath, ...) fails. This runs after the folder PIDL was successfully parsed, so the directory resolved but the specific file inside it could not be converted to an ITEMIDLIST. The HRESULT identifies the precise shell failure.","triggerScenarios":"The file portion of filePath does not exist (folder exists but file was deleted between enumeration and selection); filePath points to a virtual item the shell cannot parse; the path has trailing characters/spaces that break parsing; the file is on a disconnected network location; permission denied to enumerate the file's PIDL.","commonSituations":"OpenFolderAndSelectFile invoked on a stale result whose target file was renamed/deleted/moved; race between the search index and the filesystem; a file path with a trailing slash or space; recently-unmounted drive where the folder cached but the file is unreachable.","solutions":["Verify File.Exists(filePath) immediately before calling OpenFolderAndSelectFile (the file may have been removed since the result was generated).","Decode the HRESULT (0x80070002 file-not-found, 0x80070003 path-not-found, 0x80070005 access-denied) for specifics.","If the file was renamed, refresh the result list before retrying.","Trim trailing whitespace/slashes from the path before parsing."],"exampleFix":"// before\nvar hrFile = PInvoke.SHParseDisplayName(filePath, null, out pidlFile, 0, out _);\nif (hrFile.Failed) throw new COMException(\"Failed to parse file path\", hrFile);\n\n// after — existence check + graceful fallback\nif (!File.Exists(filePath))\n{\n    // open the folder instead of selecting a missing file\n    PInvoke.SHParseDisplayName(folderPath, null, out pidlFile, 0, out _);\n}\nelse\n{\n    var hrFile = PInvoke.SHParseDisplayName(filePath, null, out pidlFile, 0, out _);\n    if (hrFile.Failed) throw new COMException(\"Failed to parse file path\", hrFile);\n}","handlingStrategy":"validation","validationCode":"if (!File.Exists(filePath))\n{ // open folder alone instead of selecting a missing file\n  Process.Start(\"explorer.exe\", Path.GetDirectoryName(filePath)); return; }","typeGuard":"null","tryCatchPattern":"try { Win32Helper.OpenFolderAndSelectFile(filePath); }\ncatch (COMException ex) when (ex.Message.Contains(\"file path\"))\n{ Log.Warn(...); Process.Start(\"explorer.exe\", $\"/select,\\\"{filePath}\\\"\"); }","preventionTips":["Verify File.Exists(filePath) immediately before the call (files may be renamed/deleted since the result list was built).","Trim trailing spaces/slashes from paths before parsing.","Refresh stale result lists before re-selecting.","Decode the HRESULT to classify not-found vs access-denied."],"tags":["win32","shell","com","filesystem"],"backgroundTag":null,"analyzedSha":"7fc63b07bbaa10a0f0b2601487913fcba9ed24b0","analyzedAt":"2026-08-13T14:54:20.914Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}