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
- 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.
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
- 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.
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
- Source '{0}' is unable to be parsed
- The location for the template already exists. You can:{0} 1.
- Unable to find path to requested template '{0}'. Path should
- An exception occurred while copying files to '{0}'
AI-assisted analysis of chocolatey/choco@0d5abdd10c (2026-08-13).
Data as JSON: /api/errors/b1a22c29c47929e9.
Report an issue: GitHub.