ppy/osu · error · ArgumentException

Destination provided already has files or directories presen

Error message

Destination provided already has files or directories present

What it means

Thrown by MigratableStorage.Migrate when the destination directory already exists AND contains files or directories. The migration requires an empty target to avoid clobbering existing data; a non-empty destination is hard-aborted before CopyRecursive.

Source

Thrown at osu.Game/IO/MigratableStorage.cs:63

        {
            var source = new DirectoryInfo(GetFullPath("."));
            var destination = new DirectoryInfo(newStorage.GetFullPath("."));

            // using Uri is the easiest way to check equality and contains (https://stackoverflow.com/a/7710620)
            var sourceUri = new Uri(source.FullName + Path.DirectorySeparatorChar);
            var destinationUri = new Uri(destination.FullName + Path.DirectorySeparatorChar);

            if (sourceUri == destinationUri)
                throw new ArgumentException("Destination provided is already the current location", destination.FullName);

            if (sourceUri.IsBaseOf(destinationUri))
                throw new ArgumentException("Destination provided is inside the source", destination.FullName);

            // ensure the new location has no files present, else hard abort
            if (destination.Exists)
            {
                if (destination.GetFiles().Length > 0 || destination.GetDirectories().Length > 0)
                    throw new ArgumentException("Destination provided already has files or directories present", destination.FullName);
            }

            CopyRecursive(source, destination);
            ChangeTargetStorage(newStorage);

            return DeleteRecursive(source);
        }

        protected bool DeleteRecursive(DirectoryInfo target, bool topLevelExcludes = true)
        {
            bool allFilesDeleted = true;

            foreach (System.IO.FileInfo fi in target.GetFiles())
            {
                if (topLevelExcludes && IgnoreFiles.Contains(fi.Name))
                    continue;

                if (IgnoreSuffixes.Any(suffix => fi.Name.EndsWith(suffix, StringComparison.Ordinal)))

View on GitHub (pinned to d9c73e12ad)

Solutions

  1. Point migration at a fresh, empty directory; create one if needed (the method itself does not).
  2. If re-running after a failure, clean the destination of leftover files first, or pick a new empty folder.
  3. In the picker UI, warn/disable 'Migrate' when the chosen folder is non-empty.

Example fix

// before
storage.Migrate(new DesktopStorage(existingNonEmptyPath, host)); // throws

// after
string target = Path.Combine(baseDir, "osu-new");
Directory.CreateDirectory(target);
// ensure empty
if (Directory.EnumerateFileSystemEntries(target).Any())
    throw new InvalidOperationException("Migration target must be empty.");
storage.Migrate(new DesktopStorage(target, host));
Defensive patterns

Strategy: validation

Validate before calling

var dest = new DirectoryInfo(newPath);
if (dest.Exists && (dest.GetFiles().Length > 0 || dest.GetDirectories().Length > 0))
    throw new InvalidOperationException("Migration target must be empty.");

Type guard

static bool IsEmptyOrMissing(string path)
{ var d = new DirectoryInfo(path); return !d.Exists || (!d.EnumerateFiles().Any() && !d.EnumerateDirectories().Any()); }

Try / catch

try { storage.Migrate(target); }
catch (ArgumentException ex) when (ex.Message.Contains("files or directories present"))
{ /* ask user to pick an empty folder */ }

Prevention

When it happens

Trigger: Calling Migrate(newStorage) where newStorage.GetFullPath(".") exists and is non-empty (GetFiles().Length > 0 || GetDirectories().Length > 0). Re-running a migration into a previously-used folder, or pointing at a folder the user already has data in.

Common situations: User selects a non-empty folder (old osu! install, documents, desktop) as the new data location; a retry of a failed migration left partial files behind in the target.

Related errors


AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13). Data as JSON: /api/errors/c17ad51df8fed05e. Report an issue: GitHub.