peass-ng/PEASS-ng · error · DirectoryNotEmptyException

ERROR_DIR_NOT_EMPTY

ERROR_DIR_NOT_EMPTY

Error message

({145}) The directory is not empty: [{junctionPath}]

What it means

Directory.CreateJunctionCore throws DirectoryNotEmptyException (Win32 error 145, ERROR_DIR_NOT_EMPTY) when the junction target path already exists as a directory but still contains files or subdirectories. AlphaFS refuses to convert a non-empty existing folder into a junction, because doing so would make the existing content unreachable through the junction point. The check is done via IsEmptyCore before throwing.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/Directory Class/Directory Core Methods/Directory.CreateJunctionCore.cs:103

         File.ThrowIOExceptionIfFsoExist(transaction, false, directoryPath, pathFormat);
         File.ThrowIOExceptionIfFsoExist(transaction, false, junctionPath, pathFormat);


         // Check for existing directory junction folder.
         if (File.ExistsCore(transaction, true, junctionPath, pathFormat))
         {
            if (overwrite)
            {
               DeleteDirectoryCore(transaction, null, junctionPath, true, true, true, pathFormat);

               CreateDirectoryCore(true, transaction, junctionPath, null, null, false, pathFormat);
            }

            else
            {
               // Ensure the folder is empty.
               if (!IsEmptyCore(transaction, junctionPath, pathFormat))
                  throw new DirectoryNotEmptyException(junctionPath, true);

               throw new AlreadyExistsException(junctionPath, true);
            }
         }


         // Create the folder and convert it to a directory junction.
         CreateDirectoryCore(true, transaction, junctionPath, null, null, false, pathFormat);

         using (var safeHandle = OpenDirectoryJunction(transaction, junctionPath, pathFormat))
            Device.CreateDirectoryJunction(safeHandle, directoryPath);


         // Copy the target date and time stamps to the directory junction.
         if (copyTargetTimestamps)
            File.CopyTimestampsCore(transaction, true, directoryPath, junctionPath, true, pathFormat);

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Empty the target directory (delete or move its contents) before calling CreateJunction.
  2. Check Directory.IsEmpty(path) before creating the junction and delete the folder if it is non-empty but disposable.
  3. Delete the existing directory entirely and let CreateJunction create a fresh one (CreateJunctionCore calls CreateDirectoryCore afterward).
  4. Catch DirectoryNotEmptyException and surface a clear message telling the user the junction target must be empty.
  5. If the existing folder's contents must be preserved, move them to the real target location first, then create the junction at the original path.

Example fix

// before
Directory.CreateJunction(@"C:\link", @"D:\realTarget"); // fails if C:\link exists and is non-empty
// after
if (Directory.Exists(linkPath) && !Directory.IsEmpty(linkPath))
    Directory.Delete(linkPath, true);
Directory.CreateJunction(linkPath, realTarget);
Defensive patterns

Strategy: validation

Validate before calling

if (Directory.Exists(junctionPath) && !Directory.IsEmpty(junctionPath))
    throw new InvalidOperationException($"Junction target {junctionPath} must be empty");

Try / catch

try { Directory.CreateJunction(junctionPath, targetPath); }
catch (DirectoryNotEmptyException ex) { logger.LogError(ex, "Junction target not empty: {Path}", junctionPath); }

Prevention

When it happens

Trigger: Calling Directory.CreateJunction (or CreateJunctionTransacted) with a junctionPath that already exists as a directory containing one or more files/subdirectories. The path exists branch of CreateJunctionCore runs IsEmptyCore, which returns false and raises this exception instead of AlreadyExistsException.

Common situations: Re-running a setup script that previously partially created a junction and left temp files inside the target folder; pointing a junction at an existing data directory (e.g. moving a profile/cache folder) without emptying it first; a failed prior junction deletion that left contents behind.

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/ac7598a96dc09628. Report an issue: GitHub.