peass-ng/PEASS-ng · error · AlreadyExistsException

ERROR_ALREADY_EXISTS

ERROR_ALREADY_EXISTS

Error message

({183}) Cannot create a file when that file already exists: [{junctionPath}]

What it means

Directory.CreateJunctionCore throws AlreadyExistsException (Win32 error 183, ERROR_ALREADY_EXISTS) when the junction path already exists as an EMPTY directory (or is otherwise already present) and cannot be created again. The existence branch first checks IsEmptyCore; if the folder is empty it falls through to AlreadyExistsException rather than attempting creation. It means 'you asked me to create something that is already there'.

Source

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


         // 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);


         return junctionPath;
      }

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Check Directory.Exists(junctionPath) before creating and skip creation if it already exists.
  2. Delete the existing empty directory first, then call CreateJunction.
  3. Catch AlreadyExistsException and treat it as a success/no-op if a junction at that path is acceptable.
  4. Use Directory.GetLinkTargetInfo to verify the existing item is already the junction you want before deciding to recreate it.

Example fix

// before
Directory.CreateJunction(@"C:\link", @"D:\target"); // throws if C:\link exists
// after
if (!Directory.Exists(linkPath))
    Directory.CreateJunction(linkPath, targetPath);
Defensive patterns

Strategy: validation

Validate before calling

if (Directory.Exists(junctionPath))
    return; // already created; skip or verify it points at the right target

Try / catch

try { Directory.CreateJunction(junctionPath, targetPath); }
catch (AlreadyExistsException) { /* treat as no-op if re-runs are expected */ }

Prevention

When it happens

Trigger: Calling Directory.CreateJunction / CreateJunctionTransacted with a junctionPath that already exists as an empty directory. Also occurs on any re-invocation without checking existence first, since CreateDirectoryCore would hit ERROR_ALREADY_EXISTS.

Common situations: Idempotency mistakes: setup scripts run twice; a junction was created by a previous run or another installer; unit tests that do not clean up fixtures between runs.

Related errors


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