{"record":{"id":"c17ad51df8fed05e","repo":"ppy/osu","slug":"destination-provided-already-has-files-or-director","errorCode":null,"errorMessage":"Destination provided already has files or directories present","messagePattern":"Destination provided already has files or directories present","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"osu.Game/IO/MigratableStorage.cs","lineNumber":63,"sourceCode":"        {\r\n            var source = new DirectoryInfo(GetFullPath(\".\"));\r\n            var destination = new DirectoryInfo(newStorage.GetFullPath(\".\"));\r\n\r\n            // using Uri is the easiest way to check equality and contains (https://stackoverflow.com/a/7710620)\r\n            var sourceUri = new Uri(source.FullName + Path.DirectorySeparatorChar);\r\n            var destinationUri = new Uri(destination.FullName + Path.DirectorySeparatorChar);\r\n\r\n            if (sourceUri == destinationUri)\r\n                throw new ArgumentException(\"Destination provided is already the current location\", destination.FullName);\r\n\r\n            if (sourceUri.IsBaseOf(destinationUri))\r\n                throw new ArgumentException(\"Destination provided is inside the source\", destination.FullName);\r\n\r\n            // ensure the new location has no files present, else hard abort\r\n            if (destination.Exists)\r\n            {\r\n                if (destination.GetFiles().Length > 0 || destination.GetDirectories().Length > 0)\r\n                    throw new ArgumentException(\"Destination provided already has files or directories present\", destination.FullName);\r\n            }\r\n\r\n            CopyRecursive(source, destination);\r\n            ChangeTargetStorage(newStorage);\r\n\r\n            return DeleteRecursive(source);\r\n        }\r\n\r\n        protected bool DeleteRecursive(DirectoryInfo target, bool topLevelExcludes = true)\r\n        {\r\n            bool allFilesDeleted = true;\r\n\r\n            foreach (System.IO.FileInfo fi in target.GetFiles())\r\n            {\r\n                if (topLevelExcludes && IgnoreFiles.Contains(fi.Name))\r\n                    continue;\r\n\r\n                if (IgnoreSuffixes.Any(suffix => fi.Name.EndsWith(suffix, StringComparison.Ordinal)))\r","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game/IO/MigratableStorage.cs#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Point migration at a fresh, empty directory; create one if needed (the method itself does not).","If re-running after a failure, clean the destination of leftover files first, or pick a new empty folder.","In the picker UI, warn/disable 'Migrate' when the chosen folder is non-empty."],"exampleFix":"// before\nstorage.Migrate(new DesktopStorage(existingNonEmptyPath, host)); // throws\n\n// after\nstring target = Path.Combine(baseDir, \"osu-new\");\nDirectory.CreateDirectory(target);\n// ensure empty\nif (Directory.EnumerateFileSystemEntries(target).Any())\n    throw new InvalidOperationException(\"Migration target must be empty.\");\nstorage.Migrate(new DesktopStorage(target, host));","handlingStrategy":"validation","validationCode":"var dest = new DirectoryInfo(newPath);\nif (dest.Exists && (dest.GetFiles().Length > 0 || dest.GetDirectories().Length > 0))\n    throw new InvalidOperationException(\"Migration target must be empty.\");","typeGuard":"static bool IsEmptyOrMissing(string path)\n{ var d = new DirectoryInfo(path); return !d.Exists || (!d.EnumerateFiles().Any() && !d.EnumerateDirectories().Any()); }","tryCatchPattern":"try { storage.Migrate(target); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"files or directories present\"))\n{ /* ask user to pick an empty folder */ }","preventionTips":["Create a fresh empty directory for migration rather than reusing existing folders.","After a failed migration, clean partial files from the target before retrying.","In the picker, warn when the chosen folder is non-empty."],"tags":["filesystem","migration","storage","validation","safety"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}