{"record":{"id":"7f9591b04e9183fc","repo":"puppetlabs/puppet","slug":"movefileex-source-target-flags-to-s-8","errorCode":null,"errorMessage":"MoveFileEx(#{source}, #{target}, #{flags.to_s(8)})","messagePattern":"MoveFileEx\\(#(.+?), #(.+?), #(.+?)\\)","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/file.rb","lineNumber":44,"sourceCode":"      flags,\n      FFI::Pointer::NULL,\n      FFI::Pointer::NULL\n    )\n\n    return true if result != FFI::WIN32_FALSE\n\n    raise Puppet::Util::Windows::Error, \"ReplaceFile(#{target}, #{source})\"\n  end\n  module_function :replace_file\n\n  def move_file_ex(source, target, flags = 0)\n    result = MoveFileExW(wide_string(source.to_s),\n                         wide_string(target.to_s),\n                         flags)\n\n    return true if result != FFI::WIN32_FALSE\n\n    raise Puppet::Util::Windows::Error, \"MoveFileEx(#{source}, #{target}, #{flags.to_s(8)})\"\n  end\n  module_function :move_file_ex\n\n  def symlink(target, symlink)\n    flags = File.directory?(target) ? 0x1 : 0x0\n    result = CreateSymbolicLinkW(wide_string(symlink.to_s),\n                                 wide_string(target.to_s), flags)\n    return true if result != FFI::WIN32_FALSE\n\n    raise Puppet::Util::Windows::Error, \"CreateSymbolicLink(#{symlink}, #{target}, #{flags.to_s(8)})\"\n  end\n  module_function :symlink\n\n  def exist?(path)\n    path = path.to_str if path.respond_to?(:to_str) # support WatchedFile\n    path = path.to_s # support String and Pathname\n\n    seen_paths = []","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/file.rb#L26-L62","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nPuppet::Util::Windows::File.move_file_ex(src, dst)  # dst exists -> ERROR_ALREADY_EXISTS\n\n// after\nMOVEFILE_REPLACE_EXISTING = 0x1\nPuppet::Util::Windows::File.move_file_ex(src, dst, MOVEFILE_REPLACE_EXISTING)","handlingStrategy":"try-catch","validationCode":"dst_exists = Puppet::Util::Windows::File.get_attributes(target, false) != Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES\nflags |= 0x1 if dst_exists  # MOVEFILE_REPLACE_EXISTING","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Util::Windows::File.move_file_ex(source, target, flags)\nrescue Puppet::Util::Windows::Error => e\n  raise \"target exists, pass MOVEFILE_REPLACE_EXISTING\" if e.code == 183\n  raise \"file locked (#{e.message})\" if e.code == 32\n  raise \"cross-volume move: copy+delete instead\" if e.code == 17\n  raise\nend","preventionTips":["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"],"tags":["windows","file-system","win32-api","ffi","file-move","puppet"],"backgroundTag":"win32-file-move-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}