{"record":{"id":"b1a22c29c47929e9","repo":"chocolatey/choco","slug":"cannot-move-or-delete-the-root-of-the-system-drive","errorCode":null,"errorMessage":"Cannot move or delete the root of the system drive","messagePattern":"Cannot move or delete the root of the system drive","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"critical","filePath":"src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs","lineNumber":709,"sourceCode":"\r\n        public void MoveDirectory(string directoryPath, string newDirectoryPath)\r\n        {\r\n            MoveDirectory(directoryPath, newDirectoryPath, useFileMoveFallback: true, isSilent: false);\r\n        }\r\n\r\n        public void MoveDirectory(string directoryPath, string newDirectoryPath, bool useFileMoveFallback, bool isSilent)\r\n        {\r\n            if (string.IsNullOrWhiteSpace(directoryPath) || string.IsNullOrWhiteSpace(newDirectoryPath))\r\n            {\r\n                throw new ApplicationException(\"You must provide a directory to move from or to.\");\r\n            }\r\n\r\n            // Linux / macOS do not have a SystemDrive environment variable, instead, everything is under \"/\"\r\n            var systemDrive = Platform.GetPlatform() == PlatformType.Windows ? Environment.GetEnvironmentVariable(EnvironmentVariables.System.SystemDrive) : \"/\";\r\n\r\n            if (CombinePaths(directoryPath, \"\").IsEqualTo(CombinePaths(systemDrive, \"\")))\r\n            {\r\n                throw new ApplicationException(\"Cannot move or delete the root of the system drive\");\r\n            }\r\n\r\n            try\r\n            {\r\n                this.Log().Debug(ChocolateyLoggers.Verbose, \"Moving '{0}'{1} to '{2}'\".FormatWith(directoryPath, Environment.NewLine, newDirectoryPath));\r\n                AllowRetries(\r\n                    () =>\r\n                    {\r\n                        try\r\n                        {\r\n                            Directory.Move(directoryPath, newDirectoryPath);\r\n                        }\r\n                        catch (IOException)\r\n                        {\r\n                            Alphaleonis.Win32.Filesystem.Directory.Move(directoryPath, newDirectoryPath);\r\n                        }\r\n                    }, isSilent: isSilent);\r\n            }\r","sourceCodeStart":691,"sourceCodeEnd":727,"githubUrl":"https://github.com/chocolatey/choco/blob/0d5abdd10cc177a141e69547cad6935b419b6c17/src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs#L691-L727","documentation":"Thrown by DotNetFileSystem.MoveDirectory as a safety guard when the source directory path, after normalization with CombinePaths, equals the system drive root. On Windows the system drive comes from the SystemDrive env var (typically C:\\); on Linux/macOS it is '/'. Moving or deleting the root is refused outright to prevent catastrophic data loss.","triggerScenarios":"Calling MoveDirectory with directoryPath (or newDirectoryPath resolving to source) set to the system drive root, e.g. C:\\ on Windows or / on Linux. The equality check IsEqualTo against CombinePaths(systemDrive, '') matches before any actual move is attempted.","commonSituations":"Bugs in path construction that drop a subfolder segment and collapse to the drive root; misconfigured install locations that resolve an env var to empty and concatenate to the bare drive; tests using a fake filesystem where the system drive constant is unexpectedly hit.","solutions":["Log/inspect directoryPath and newDirectoryPath before the call and confirm neither equals the system drive root.","Fix the path-building logic so an empty env var or missing subfolder cannot reduce the path to the bare drive root.","Add a precondition assertion in your own code rejecting root paths before delegating to MoveDirectory."],"exampleFix":"// before (env var empty collapses to root)\nvar root = Environment.GetEnvironmentVariable(\"CHOCO_ROOT\");\nvar src = Path.Combine(root ?? \"\", \"lib\");\nfs.MoveDirectory(src, dest, true, false); // src may resolve toward drive root\n\n// after\nif (string.IsNullOrWhiteSpace(root)) throw new InvalidOperationException(\"CHOCO_ROOT not set\");\nfs.MoveDirectory(Path.Combine(root, \"lib\"), dest, true, false);","handlingStrategy":"validation","validationCode":"string systemDrive = System.OperatingSystem.IsWindows()\n    ? (Environment.GetEnvironmentVariable(\"SystemDrive\") ?? @\"C:\\\")\n    : \"/\";\nstring normalized = Path.GetFullPath(directoryPath + Path.DirectorySeparatorChar);\nif (string.IsNullOrWhiteSpace(directoryPath) ||\n    normalized.Equals(Path.GetFullPath(systemDrive + Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase))\n{\n    throw new ArgumentException(\"Refusing to move the system drive root.\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    fs.MoveDirectory(src, dest, true, false);\n}\ncatch (ApplicationException ex) when (ex.Message.Contains(\"root of the system drive\"))\n{\n    logger.Error(ex.Message + \" Source path resolved to the drive root; fix path construction.\");\n    throw;\n}","preventionTips":["Never build a path by concatenating a possibly-empty env var with a subfolder; assert the base is non-empty first.","Add an integration test that asserts MoveDirectory rejects the system drive root for your path inputs."],"tags":["filesystem","safety-guard","path-validation","destructive"],"backgroundTag":null,"analyzedSha":"0d5abdd10cc177a141e69547cad6935b419b6c17","analyzedAt":"2026-08-13T18:33:03.301Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}