puppetlabs/puppet · error · Puppet::Util::Windows::Error
MoveFileEx(#{source}, #{target}, #{flags.to_s(8)})
Error message
MoveFileEx(#{source}, #{target}, #{flags.to_s(8)}) What it means
Puppet::Util::Windows::File.move_file_ex wraps MoveFileExW; on FALSE it raises Puppet::Util::Windows::Error with source, target, and the flags in octal (e.g. flags=1 means MOVEFILE_REPLACE_EXISTING). The appended Win32 text and e.code identify the real cause - usually target-exists, sharing violation, or cross-device move.
Source
Thrown at lib/puppet/util/windows/file.rb:44
flags,
FFI::Pointer::NULL,
FFI::Pointer::NULL
)
return true if result != FFI::WIN32_FALSE
raise Puppet::Util::Windows::Error, "ReplaceFile(#{target}, #{source})"
end
module_function :replace_file
def move_file_ex(source, target, flags = 0)
result = MoveFileExW(wide_string(source.to_s),
wide_string(target.to_s),
flags)
return true if result != FFI::WIN32_FALSE
raise Puppet::Util::Windows::Error, "MoveFileEx(#{source}, #{target}, #{flags.to_s(8)})"
end
module_function :move_file_ex
def symlink(target, symlink)
flags = File.directory?(target) ? 0x1 : 0x0
result = CreateSymbolicLinkW(wide_string(symlink.to_s),
wide_string(target.to_s), flags)
return true if result != FFI::WIN32_FALSE
raise Puppet::Util::Windows::Error, "CreateSymbolicLink(#{symlink}, #{target}, #{flags.to_s(8)})"
end
module_function :symlink
def exist?(path)
path = path.to_str if path.respond_to?(:to_str) # support WatchedFile
path = path.to_s # support String and Pathname
seen_paths = []View on GitHub (pinned to e227c27540)
Solutions
- Pass MOVEFILE_REPLACE_EXISTING (0x1) when overwriting an existing target is intended
- Map e.code: 183 = target exists, 32 = locked, 17 = cross-volume, 5 = access denied, 2/3 = missing
- For cross-volume moves, copy + delete instead of move_file_ex
- Close/retry when code 32 (sharing violation) - the lock is often transient
Example fix
// before Puppet::Util::Windows::File.move_file_ex(src, dst) # dst exists -> ERROR_ALREADY_EXISTS // after MOVEFILE_REPLACE_EXISTING = 0x1 Puppet::Util::Windows::File.move_file_ex(src, dst, MOVEFILE_REPLACE_EXISTING)
Defensive patterns
Strategy: try-catch
Validate before calling
dst_exists = Puppet::Util::Windows::File.get_attributes(target, false) != Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES flags |= 0x1 if dst_exists # MOVEFILE_REPLACE_EXISTING
Try / catch
begin
Puppet::Util::Windows::File.move_file_ex(source, target, flags)
rescue Puppet::Util::Windows::Error => e
raise "target exists, pass MOVEFILE_REPLACE_EXISTING" if e.code == 183
raise "file locked (#{e.message})" if e.code == 32
raise "cross-volume move: copy+delete instead" if e.code == 17
raise
end Prevention
- Pass MOVEFILE_REPLACE_EXISTING (0x1) whenever the destination may exist
- Use copy+delete for cross-volume moves instead of relying on MoveFileEx
- Close your own handles to the file before moving it
When it happens
Trigger: move_file_ex(src, dst) where dst already exists and flags lacks MOVEFILE_REPLACE_EXISTING (0x1, raises ERROR_ALREADY_EXISTS/183); the file is open by another process without MOVEFILE_WRITE_THROUGH semantics (32); src and dst are on different volumes for a rename-style move (17, ERROR_NOT_SAME_DEVICE); insufficient rights (5); missing path (2/3).
Common situations: Deploy scripts moving artifacts into place where the destination from a previous run still exists; moves across drive letters or mounted volumes; files held open by editors/AV during Puppet runs; agents without modify rights on the destination folder.
Related errors
- ReplaceFile(#{target}, #{source})
- GetFileAttributes(#{file_name})
- Failed to set file attributes
- CreateFile(#{file_name}, #{desired_access.to_s(8)}, #{share_
- Failed to call GetLongPathName
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/7f9591b04e9183fc.
Report an issue: GitHub.