{"record":{"id":"0a022c116045944a","repo":"BCUninstaller/Bulk-Crap-Uninstaller","slug":"path-root-is-invalid-or-missing","errorCode":null,"errorMessage":"Path root is invalid or missing","messagePattern":"Path root is invalid or missing","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"source/KlocTools/Tools/RegistryTools.cs","lineNumber":249,"sourceCode":"                case HklmShortRootName:\n                    rootKey = Registry.LocalMachine;\n                    break;\n                case HkcrShortRootName:\n                    rootKey = Registry.ClassesRoot;\n                    break;\n                case HkcuShortRootName:\n                    rootKey = Registry.CurrentUser;\n                    break;\n                case HkuShortRootName:\n                case HkuShortRootName2:\n                    rootKey = Registry.Users;\n                    break;\n                case HkccShortRootName:\n                    rootKey = Registry.CurrentConfig;\n                    break;\n\n                default:\n                    throw new ArgumentException(\"Path root is invalid or missing\");\n            }\n\n            return rootKey;\n        }\n\n        /// <summary>\n        ///     Return registry key at supplied path. If the key or its parents don't exist, create them before returning.\n        ///     The returned RegistryKey is writable.\n        /// </summary>\n        /// <param name=\"fullPath\">Path of the key to open or create. Not case-sensitive.</param>\n        public static RegistryKey CreateSubKeyRecursively(string fullPath)\n        {\n            if (fullPath == null)\n                throw new ArgumentNullException(nameof(fullPath));\n\n            if (fullPath.Length < 4)\n                throw new ArgumentException(\"Path is too short/invalid\");\n","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/BCUninstaller/Bulk-Crap-Uninstaller/blob/608321de98e92297377b1eb69029af55c25504a1/source/KlocTools/Tools/RegistryTools.cs#L231-L267","documentation":"Thrown by GetRootHive when the parsed root segment of a registry path does not match any of the supported hive aliases (HKLM, HKCR, HKCU, HKU/HKUS, HKCC, or their HKEY_* long forms). The library refuses to guess a hive, so any unrecognized leading token is treated as a malformed path. It is an ArgumentException, raised after GetKeyRoot has already normalized the leading segment to upper-case.","triggerScenarios":"Calling OpenRegistryKey / CreateSubKeyRecursively / GetRootHive with a path whose first segment is misspelled (e.g. 'HKEY_LOCAL_MASHINE', 'HKLMX'), uses an unsupported hive (HKEY_CURRENT_USER_LOCAL_SETTINGS, HKEY_PERFORMANCE_DATA, HKEY_DYN_DATA), or starts with a relative/empty token before the first backslash.","commonSituations":"Copy-pasting a registry path from documentation that uses a non-canonical hive name; building paths via string concatenation where the root constant is wrong; paths imported from a .reg file using hive variants the switch does not enumerate; locale-specific typos.","solutions":["Spell the root as one of: HKLM, HKCR, HKCU, HKU, HKUS, HKCC, or HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_USERS, HKEY_CURRENT_CONFIG.","Ensure the root is separated from the rest by a single backslash and that nothing precedes it (no leading whitespace, no drive-style prefixes).","If you need an unsupported hive (e.g. HKEY_PERFORMANCE_DATA), open it directly via Microsoft.Win32.Registry instead of routing through this helper.","Log fullPath.ToUpperInvariant() at the call site to see exactly which token the switch is rejecting."],"exampleFix":"// before\nvar k = RegistryTools.OpenRegistryKey(\"HKEY_LOCAL_MASHINE\\\\Software\\\\Foo\", true);\n\n// after\nvar k = RegistryTools.OpenRegistryKey(\"HKEY_LOCAL_MACHINE\\\\Software\\\\Foo\", true);\n// or short form\nvar k = RegistryTools.OpenRegistryKey(\"HKLM\\\\Software\\\\Foo\", true);","handlingStrategy":"validation","validationCode":"private static readonly HashSet<string> ValidRoots = new(StringComparer.OrdinalIgnoreCase)\n{\n    \"HKLM\",\"HKCR\",\"HKCU\",\"HKU\",\"HKUS\",\"HKCC\",\n    \"HKEY_LOCAL_MACHINE\",\"HKEY_CLASSES_ROOT\",\"HKEY_CURRENT_USER\",\"HKEY_USERS\",\"HKEY_CURRENT_CONFIG\"\n};\nprivate static bool IsRootValid(string fullPath)\n{\n    if (string.IsNullOrWhiteSpace(fullPath)) return false;\n    var seg = fullPath.Split('\\\\', '/')[0];\n    return ValidRoots.Contains(seg);\n}","typeGuard":"static bool IsLikelyRegistryPath(string s) =>\n    !string.IsNullOrWhiteSpace(s)\n    && s.Length >= 4\n    && (s.StartsWith(\"HK\", StringComparison.OrdinalIgnoreCase)\n        || s.StartsWith(\"HKEY_\", StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { var k = RegistryTools.OpenRegistryKey(path, writable); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Path root is invalid\"))\n{ /* log path.ToUpperInvariant() and surface to user */ }","preventionTips":["Keep a single shared constant for the accepted hive aliases and build all paths from it.","Reject paths at the UI boundary before they reach the registry layer.","Add a unit test that round-trips each supported alias through OpenRegistryKey."],"tags":["registry","argument-validation","path-parsing","windows","csharp"],"backgroundTag":null,"analyzedSha":"608321de98e92297377b1eb69029af55c25504a1","analyzedAt":"2026-08-13T12:17:35.389Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}