fs.copyFile with COPYFILE_FICLONE flag does not overwrite destination if it exists

  • Version: 10.15.2, 11.14.0
  • Platform: Darwin Kernel Version 18.2.0 x86_64
  • Subsystem: fs

According to https://github.com/nodejs/node/blob/master/doc/api/fs.md#fscopyfilesrc-dest-flags-callback the default behaviour of fs.copyFile is to overwrite the destination if it already exists. The documentation further gives the example of using fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE to create a copy-on-write reflink which fails if the destination exists.

const fs = require('fs');

// first copy succeeds
fs.copyFile('source.txt', 'destination.txt', fs.constants.COPYFILE_FICLONE, (err) => {
  if (err) throw err;
  console.log('source.txt was copied to destination.txt');
});

// destination now exists, causing copy operation to fail
fs.copyFile('source.txt', 'destination.txt', fs.constants.COPYFILE_FICLONE, (err) => {
  if (err) throw err;
  console.log('source.txt was copied to destination.txt');
});

{ [Error: EEXIST: file already exists, copyfile 'source.txt' -> 'destination.txt']
errno: -17,
code: 'EEXIST',
syscall: 'copyfile',
path: 'source.txt',
dest: 'destination.txt' }