Move operation error "EXDEV: cross-device link not permitted, rename"
I ran into problem with moving a folder for a physical drive to another (mounted) drive.
My application is running at D:\.
fsn.move('source\dir', 'T:\target\dir')
Error: EXDEV: cross-device link not permitted, rename 'D:\source\dir' -> 'T:\target\dir'
{
errno: -4037,
code: 'EXDEV',
syscall: 'rename',
path: 'D:\source\dir',
dest: 'T:\target\dir'
}
The workaround is
fsn.move(path.resolve('source\dir'), 'T:\target\dir')
Here is my pull request
I checked the implementation of fsn.move, it seems source and destination are resolved on the fly, but not everywhere. Is there a particular reason for that?
https://github.com/bdistin/fs-nextra/blob/928bb203d87c8ed4d521b69e23128095a3f5a81e/src/nextra/move.ts#L26-L44
I have no idea how you were able to trigger that error because cross-device/EXDEV moves are handled with this code: https://github.com/bdistin/fs-nextra/blob/928bb203d87c8ed4d521b69e23128095a3f5a81e/src/nextra/move.ts#L47-L55
Resolving the path, other than checking to see if the source and destination are the same, shouldn't have any relationship with EXDEV.
I generally report this issue when I move a file from drive D to drive T (which is my mounted RAMDISK).
Anyway, if paths are resolved before calling fsn.move, it will not show error.
Do you have a node version and a stack trace? It's one thing for the return await not being caught by the try-catch in move. It's another thing for a potential bug with copy, which your patch could only ever partially solve.
I'm using nodejs v12.20.1 and (last LTS version supported by Windows 7)
Today I tried to provide more details, however I cannot reproduce the EXDEV error, but see another one. The initial propose of using this function is just to move a folder (including all children) to another. Maybe my usage is not right?
Preparation:
Create a folder temp and create an empty file abc.txt in it
Test 1: Move folder to same drive
fsn.move('./temp/', 'c:/fsntest')
It passed
Test 2: Move folder to another physical drive
fsn.move('./temp/', 'd:/fsntest')
Promise {
} Error: FS-NEXTRA: Copying a parent directory into a child will result in an infinite loop. at copyDirectory (D:\fsntest\node_modules\fs-nextra\dist\nextra\copy.js:62:15) at startCopy (D:\fsntest\node_modules\fs-nextra\dist\nextra\copy.js:56:15) at async Object.copy [as default] (D:\fsntest\node_modules\fs-nextra\dist\nextra\copy.js:25:9) at async Object.move (D:\fsntest\node_modules\fs-nextra\dist\nextra\move.js:42:13)
Test 3: Move folder to another virtual (mounted) drive
fsn.move('./temp/', 't:/fsntest')
Promise {
} Error: FS-NEXTRA: Copying a parent directory into a child will result in an infinite loop. at copyDirectory (D:\fsntest\node_modules\fs-nextra\dist\nextra\copy.js:62:15) at startCopy (D:\fsntest\node_modules\fs-nextra\dist\nextra\copy.js:56:15) at async Object.copy [as default] (D:\fsntest\node_modules\fs-nextra\dist\nextra\copy.js:25:9) at async Object.move (D:\fsntest\node_modules\fs-nextra\dist\nextra\move.js:42:13)
Ok, so that lines up with what I had said previously. A potential bug in copy.
So this line is throwing: https://github.com/bdistin/fs-nextra/blob/master/src/nextra/copy.ts#L86
Can you throw a console.log above that isSrcKid check (in your node_modules\fs-nextra\dist\nextra\copy.js where you are testing this) to test what the resolved mySource and target are. They get path resolved in resolveCopyOptions; then directories are built off of the source and target (in startCopy) so you get the same folder name in the target directory. After that, it iterates through the directory and copies all items (files, directories, and symlinks) inside that directory to the directory just made.
Here is the details before isSrcKid check
{
mySource: './temp',
stats: Stats {
dev: 4240084544,
mode: 16822,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 6192449488425088,
size: 0,
blocks: 0,
atimeMs: 1613893809781.817,
mtimeMs: 1613893809781.817,
ctimeMs: 1613893987043.3264,
birthtimeMs: 1613893726676.264,
atime: 2021-02-21T07:50:09.782Z,
mtime: 2021-02-21T07:50:09.782Z,
ctime: 2021-02-21T07:53:07.043Z,
birthtime: 2021-02-21T07:48:46.676Z
},
target: './temp',
options: {
currentPath: 'D:\\fsntest\\temp',
targetPath: 't:\\fsntest',
filter: [Function],
overwrite: false,
preserveTimestamps: false,
errorOnExist: true
}
}
It looks like isSrcKid checks source with target without resolving the full path.
Note that I believe there are 2 bugs in my usage.
- The new issue we are check stacktrace:
Error: FS-NEXTRA: Copying a parent directory into a child will result in an infinite loop. - Once this issue is identified and fixed, I will further look into the original one.
EXDEV: cross-device link not permitted, rename. That one requires more setup. I would rather discuss these issues one by one.