# \[BUG\] Unexpected behavior moving directories to external drives

**URL:** <https://forum.juce.com/t/bug-unexpected-behavior-moving-directories-to-external-drives/59367>\
**Category:** General JUCE discussion\
**Created:** [January 4, 2024, 12:39am UTC](https://forum.juce.com/t/bug-unexpected-behavior-moving-directories-to-external-drives/59367 "2024-01-04T00:39:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![officialnsa](https://avatars.discourse-cdn.com/v4/letter/o/ecb155/32.png) [@officialnsa](https://forum.juce.com/u/officialnsa)\
**Post date:** [January 4, 2024, 12:39am UTC](https://forum.juce.com/t/bug-unexpected-behavior-moving-directories-to-external-drives/59367/1 "2024-01-04T00:39:36Z")

</div>

I’ve encountered what I believe to be a bug when attempting to move a non-empty directory to an external SSD. The operation fails, and digging into the source code I’ve found the problem:

```cpp
bool File::moveInternal (const File& dest) const
{
    if (rename (fullPath.toUTF8(), dest.getFullPathName().toUTF8()) == 0)
        return true;

    if (hasWriteAccess() && copyInternal (dest))
    {
        if (deleteFile())
            return true;

        dest.deleteFile();
    }

    return false;
}

```

Assuming that `dest` is a location on an external drive and `*this` is a `File` on the main disk, the `rename` syscall fails with `errno == EXDEV`, because `renames` are not allowed across different filesystems (my drive is `ExFAT` for Windows cross-compatibility).

After the `rename` fails, the `copyInternal` actually succeeds without a hitch. The issue is that the attempt to `deleteFile()` on the origin directory fails, because of this code:

```cpp
        if (isDirectory())
            return rmdir (fullPath.toUTF8()) == 0;

        dest.deleteFile();

```

`rmdir` doesn’t succeed here because it only operates on empty directories (fails with `errno == ENOTEMPTY`).

To me, it seems like the intention of this copy-and-delete operation would be for the entire directory to be copied over, and the source directory to be deleted alongside its contents, hence my sense that this is a bug. Furthermore, the `dest.deleteFile()` line fails for the same reason, meaning the copied destination directory still exists after the “failure”. I’m going to write a workaround in my own code, but wanted to bring this to the team’s attention.

---

<div class="post-metadata">

**Author:** ![attila](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/attila/32/11206_2.png) [@attila](https://forum.juce.com/u/attila)\
**Post date:** [January 10, 2024, 1:05pm UTC](https://forum.juce.com/t/bug-unexpected-behavior-moving-directories-to-external-drives/59367/2 "2024-01-10T13:05:33Z")

</div>

You’re right that in your case using `File::moveFileTo()` will fail and leave unwanted file system changes behind.

A change was released on `develop` that will fail the operation before making any file system changes.

> <https://github.com/juce-framework/JUCE/commit/3f52b294327a283f3e754b94a836290cbf2d58a7>

The `File::moveFileTo()` is generally not appropriate to use with directories, because the API lacks the necessary options to specify what to do in various cases when the target directory already exists and contains some files. A word about this has been added to the documentation.

In some cases it will work correctly, but when it fails, the `copyDirectoryTo()` and `deleteRecursively()` functions can be used to prescribe the required filesystem operations unambiguously.

---

<div class="post-metadata">

**Author:** ![officialnsa](https://avatars.discourse-cdn.com/v4/letter/o/ecb155/32.png) [@officialnsa](https://forum.juce.com/u/officialnsa)\
**Post date:** [January 24, 2024, 12:58am UTC](https://forum.juce.com/t/bug-unexpected-behavior-moving-directories-to-external-drives/59367/3 "2024-01-24T00:58:27Z")

</div>

Thanks for your response (and sorry for getting back to you so late). The behavior + documentation in the commit you linked are perfect, thank you for getting that in there. I was able to workaround using the copy/delete idiom you described, glad to hear that’s actually the prescription.
