chocolatey/choco · critical · ApplicationException

Cannot move or delete the root of the system drive

Error message

Cannot move or delete the root of the system drive

What it means

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.

Source

Thrown at src/chocolatey/infrastructure/filesystem/DotNetFileSystem.cs:709

        public void MoveDirectory(string directoryPath, string newDirectoryPath)
        {
            MoveDirectory(directoryPath, newDirectoryPath, useFileMoveFallback: true, isSilent: false);
        }

        public void MoveDirectory(string directoryPath, string newDirectoryPath, bool useFileMoveFallback, bool isSilent)
        {
            if (string.IsNullOrWhiteSpace(directoryPath) || string.IsNullOrWhiteSpace(newDirectoryPath))
            {
                throw new ApplicationException("You must provide a directory to move from or to.");
            }

            // Linux / macOS do not have a SystemDrive environment variable, instead, everything is under "/"
            var systemDrive = Platform.GetPlatform() == PlatformType.Windows ? Environment.GetEnvironmentVariable(EnvironmentVariables.System.SystemDrive) : "/";

            if (CombinePaths(directoryPath, "").IsEqualTo(CombinePaths(systemDrive, "")))
            {
                throw new ApplicationException("Cannot move or delete the root of the system drive");
            }

            try
            {
                this.Log().Debug(ChocolateyLoggers.Verbose, "Moving '{0}'{1} to '{2}'".FormatWith(directoryPath, Environment.NewLine, newDirectoryPath));
                AllowRetries(
                    () =>
                    {
                        try
                        {
                            Directory.Move(directoryPath, newDirectoryPath);
                        }
                        catch (IOException)
                        {
                            Alphaleonis.Win32.Filesystem.Directory.Move(directoryPath, newDirectoryPath);
                        }
                    }, isSilent: isSilent);
            }

View on GitHub (pinned to 0d5abdd10c)

Solutions

  1. Log/inspect directoryPath and newDirectoryPath before the call and confirm neither equals the system drive root.
  2. Fix the path-building logic so an empty env var or missing subfolder cannot reduce the path to the bare drive root.
  3. Add a precondition assertion in your own code rejecting root paths before delegating to MoveDirectory.

Example fix

// before (env var empty collapses to root)
var root = Environment.GetEnvironmentVariable("CHOCO_ROOT");
var src = Path.Combine(root ?? "", "lib");
fs.MoveDirectory(src, dest, true, false); // src may resolve toward drive root

// after
if (string.IsNullOrWhiteSpace(root)) throw new InvalidOperationException("CHOCO_ROOT not set");
fs.MoveDirectory(Path.Combine(root, "lib"), dest, true, false);
Defensive patterns

Strategy: validation

Validate before calling

string systemDrive = System.OperatingSystem.IsWindows()
    ? (Environment.GetEnvironmentVariable("SystemDrive") ?? @"C:\")
    : "/";
string normalized = Path.GetFullPath(directoryPath + Path.DirectorySeparatorChar);
if (string.IsNullOrWhiteSpace(directoryPath) ||
    normalized.Equals(Path.GetFullPath(systemDrive + Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase))
{
    throw new ArgumentException("Refusing to move the system drive root.");
}

Try / catch

try
{
    fs.MoveDirectory(src, dest, true, false);
}
catch (ApplicationException ex) when (ex.Message.Contains("root of the system drive"))
{
    logger.Error(ex.Message + " Source path resolved to the drive root; fix path construction.");
    throw;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of chocolatey/choco@0d5abdd10c (2026-08-13). Data as JSON: /api/errors/b1a22c29c47929e9. Report an issue: GitHub.