{"record":{"id":"62a589d3d8b725ba","repo":"Flow-Launcher/Flow.Launcher","slug":"shbindtoparent-failed","errorCode":null,"errorMessage":"SHBindToParent failed","messagePattern":"SHBindToParent failed","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenuDisplayHelper.cs","lineNumber":192,"sourceCode":"        IMalloc malloc = null;\n        IntPtr originalPidl = IntPtr.Zero;\n        IntPtr pShellFolder = IntPtr.Zero;\n        IntPtr pContextMenu = IntPtr.Zero;\n        IntPtr hMenu = IntPtr.Zero;\n        IContextMenu contextMenu = null;\n        IShellFolder shellFolder = null;\n\n        try\n        {\n            malloc = GetMalloc();\n            var hr = SHParseDisplayName(fileName, IntPtr.Zero, out var pidl, 0, out _);\n            if (hr != 0) throw new Exception(\"SHParseDisplayName failed\");\n\n            originalPidl = pidl;\n\n            var guid = typeof(IShellFolder).GUID;\n            hr = SHBindToParent(pidl, guid, out pShellFolder, ref pidl);\n            if (hr != 0) throw new Exception(\"SHBindToParent failed\");\n\n            shellFolder = (IShellFolder)Marshal.GetTypedObjectForIUnknown(pShellFolder, typeof(IShellFolder));\n            hr = shellFolder.GetUIObjectOf(\n                IntPtr.Zero, 1, new[] { pidl }, typeof(IContextMenu).GUID, IntPtr.Zero, out pContextMenu\n            );\n            if (hr != 0) throw new Exception(\"GetUIObjectOf failed\");\n\n            contextMenu = (IContextMenu)Marshal.GetTypedObjectForIUnknown(pContextMenu, typeof(IContextMenu));\n\n            hMenu = CreatePopupMenu();\n            contextMenu.QueryContextMenu(hMenu, 0, ContextMenuStartId, ContextMenuEndId, (uint)ContextMenuFlags.Explore);\n\n            var directory = Path.GetDirectoryName(fileName);\n            var invokeCommandInfo = new CMINVOKECOMMANDINFO\n            {\n                cbSize = (uint)Marshal.SizeOf(typeof(CMINVOKECOMMANDINFO)),\n                fMask = (uint)ContextMenuInvokeCommandFlags.Unicode,\n                hwnd = IntPtr.Zero,","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/Flow-Launcher/Flow.Launcher/blob/7fc63b07bbaa10a0f0b2601487913fcba9ed24b0/Plugins/Flow.Launcher.Plugin.Explorer/Helper/ShellContextMenuDisplayHelper.cs#L174-L210","documentation":"Thrown when shell32!SHBindToParent returns a non-zero HRESULT after a PIDL has been successfully parsed by SHParseDisplayName. SHBindToParent walks the PIDL to its last item and returns an IShellFolder pointer for the parent plus a child-only PIDL; failure here means the binding chain to the parent folder broke even though the item name parsed. As with error 20 the HRESULT is discarded. This call sits between parsing the PIDL and asking the parent folder for an IContextMenu.","triggerScenarios":"Binding against root pseudo-folders whose parent cannot be expressed as IShellFolder (e.g. the Desktop root, ::{CLSID} namespace roots), PIDLs that the Shell considers malformed for binding even though they parsed, item whose parent folder is a per-user virtual location that is not mounted in this session, or the PIDL memory was mutated between the two calls.","commonSituations":"User right-clicks a top-level namespace item (This PC, Recycle Bin, Network), or a control-panel CLSID path returned by a search engine; the file was renamed/moved in the same window of time so the parent no longer matches; running under an account whose profile did not finish loading so the user's Desktop parent is missing.","solutions":["Preserve the HRESULT: throw new COMException(\"SHBindToParent failed\", hr) so the failure code surfaces.","Reject CLSID-style paths (:: prefix) and known namespace roots before invoking the helper, since those have no file-system parent.","Validate the parent path with Directory.Exists(Path.GetDirectoryName(fileName)) for file-system items before calling.","Re-resolve the PIDL from the display name immediately before binding to avoid stale-PIDL races."],"exampleFix":"// before\nhr = SHBindToParent(pidl, guid, out pShellFolder, ref pidl);\nif (hr != 0) throw new Exception(\"SHBindToParent failed\");\n\n// after\nhr = SHBindToParent(pidl, guid, out pShellFolder, ref pidl);\nif (hr != 0) throw new COMException(\"SHBindToParent failed\", hr);","handlingStrategy":"validation","validationCode":"if (fileName.StartsWith(\"::\"))\n    throw new InvalidOperationException(\"Namespace-root paths have no parent IShellFolder.\");\nvar parent = Path.GetDirectoryName(fileName);\nif (!Directory.Exists(parent))\n    throw new DirectoryNotFoundException($\"Parent folder does not exist: {parent}\");","typeGuard":"static bool HasFileSystemParent(string path) => !path.StartsWith(\"::\") && Directory.Exists(Path.GetDirectoryName(path));","tryCatchPattern":"try { ShellContextMenuDisplayHelper.ExecuteContextMenuItem(fileName, menuItemId); }\ncatch (Exception ex) when (ex.Message == \"SHBindToParent failed\") { logger.Warn($\"No bindable parent for {fileName}\"); /* skip action */ }","preventionTips":["Reject CLSID/namespace-root paths before invoking.","Validate the parent directory exists.","Preserve the HRESULT for diagnosability.","Avoid holding PIDLs across long-running operations."],"tags":["win32","shell-com","context-menu","pidl","csharp"],"backgroundTag":null,"analyzedSha":"7fc63b07bbaa10a0f0b2601487913fcba9ed24b0","analyzedAt":"2026-08-13T14:54:20.914Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}