peass-ng/PEASS-ng · error · ArgumentException

MoveOptions.CopyAllowed is not allowed when using the MoveOp

Error message

MoveOptions.CopyAllowed is not allowed when using the MoveOptions.DelayUntilReboot flag.

What it means

MoveOptions.DelayUntilReboot (MOVEFILE_DELAY_UNTIL_REBOOT) cannot be combined with MoveOptions.CopyAllowed: a delayed reboot operation is registered with the session manager and cannot perform a copy fallback. VerifyDelayUntilReboot throws ArgumentException("moveOptions") when both flags are present.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/File Class/File CopyMove/File.VerifyDelayUntilReboot.cs:36

 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 *  THE SOFTWARE. 
 */

using System;
using winPEAS._3rdParty.AlphaFS;

namespace Alphaleonis.Win32.Filesystem
{
   public static partial class File
   {
      private static bool VerifyDelayUntilReboot(string sourcePath, MoveOptions? moveOptions, PathFormat pathFormat)
      {
         var delayUntilReboot = HasDelayUntilReboot(moveOptions);

         if (delayUntilReboot)
         {
            if (HasCopyAllowed(moveOptions))
               throw new ArgumentException(Resources.MoveOptionsDelayUntilReboot_Not_Allowed_With_MoveOptionsCopyAllowed, "moveOptions");


            // MoveFileXxx: (lpExistingFileName) If dwFlags specifies MOVEFILE_DELAY_UNTIL_REBOOT,
            // the file cannot exist on a remote share, because delayed operations are performed before the network is available.

            if (Path.IsUncPathCore(sourcePath, pathFormat != PathFormat.LongFullPath, false))
               throw new ArgumentException(Resources.MoveOptionsDelayUntilReboot_Not_Allowed_With_NetworkPath, "moveOptions");
         }

         return delayUntilReboot;
      }
   }
}

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Remove MoveOptions.CopyAllowed when using MoveOptions.DelayUntilReboot.
  2. If a copy fallback is required, drop DelayUntilReboot and perform the move immediately.
  3. Split the logic: attempt a normal move with CopyAllowed, and only schedule DelayUntilReboot moves for locked-file cases without CopyAllowed.

Example fix

// before
var opts = MoveOptions.CopyAllowed | MoveOptions.DelayUntilReboot; // ArgumentException
File.Move(src, dst, opts);
// after
File.Move(src, dst, MoveOptions.DelayUntilReboot);
Defensive patterns

Strategy: validation

Validate before calling

static void ValidateMoveOptions(MoveOptions opts)
{
    if (opts.HasFlag(MoveOptions.DelayUntilReboot) && opts.HasFlag(MoveOptions.CopyAllowed))
        throw new ArgumentException("MoveOptions.CopyAllowed cannot be combined with MoveOptions.DelayUntilReboot.");
}

Type guard

static bool HasIncompatibleMoveFlags(MoveOptions opts) =>
    opts.HasFlag(MoveOptions.DelayUntilReboot) && opts.HasFlag(MoveOptions.CopyAllowed);

Try / catch

try { File.Move(src, dst, moveOptions); }
catch (ArgumentException ex) when (ex.ParamName == "moveOptions")
{
    // retry without the forbidden combination
    File.Move(src, dst, moveOptions & ~MoveOptions.CopyAllowed);
}

Prevention

When it happens

Trigger: Calling File.Move / CopyMove with MoveOptions such as MoveOptions.CopyAllowed | MoveOptions.DelayUntilReboot.

Common situations: OR-ing MoveOptions flags together to get 'maximum flexibility'; copying flag combinations from code paths that used CopyAllowed alone and adding DelayUntilReboot for offline scenarios.

Related errors


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