{"record":{"id":"b17de5c836d2b262","repo":"Unity-Technologies/UnityCsReference","slug":"failed-to-delete-directory-0","errorCode":null,"errorMessage":"Failed to delete directory '{0}'.","messagePattern":"Failed to delete directory '(.+?)'\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/FileUtil.bindings.cs","lineNumber":169,"sourceCode":"        private static extern string ReadAllTextInternal(string path);\n\n        // Replaces a file.\n        public static void ReplaceFile(string src, string dst)\n        {\n            if (File.Exists(dst))\n                FileUtil.DeleteFileOrDirectory(dst);\n\n            FileUtil.CopyFileOrDirectory(src, dst);\n        }\n\n        // Replaces a directory.\n        public static void ReplaceDirectory(string src, string dst)\n        {\n            if (Directory.Exists(dst))\n            {\n                bool succesfullyDeletedDirectory = FileUtil.DeleteFileOrDirectory(dst);\n                if (succesfullyDeletedDirectory == false)\n                    throw new System.IO.IOException(string.Format(\n                        \"Failed to delete directory '{0}'.\", dst));\n            }\n            FileUtil.CopyFileOrDirectory(src, dst);\n        }\n\n        /// <summary>\n        /// Returns the absolute path and resolves physical location for the specified path if path points to Unity Virtual File System.\n        /// </summary>\n        /// <remarks>The method is equivalent to Path.GetFullPath(FileUtil.GetPhysicalPath(path)), but takes into account Unity and platform path separators.</remarks>\n        /// <param name=\"path\">The file or directory for which to obtain absolute path information.</param>\n        /// <returns>The fully qualified location of path. Path separators are Unity path separators ('/')</returns>\n        /// <example>\n        /// public class MyImporter : ScriptedImporter\n        /// {\n        ///     public override void OnImportAsset(AssetImportContext ctx)\n        ///     {\n        ///         var data = File.ReadAllText(FileUtil.PathToAbsolutePath(ctx.assetPath));\n        ///         Object objectToUse = null;","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/FileUtil.bindings.cs#L151-L187","documentation":"ReplaceDirectory ensures the destination is empty by deleting it first, then copying src into it. If the delete returns false (the native DeleteFileOrDirectory failed — locked, permissions, partial), ReplaceDirectory throws System.IO.IOException with the formatted directory path, halting before the copy. It is fail-loud by design so a half-replaced directory is never produced.","triggerScenarios":"ReplaceDirectory(src, dst) where dst is an existing directory that cannot be deleted: files inside are locked by the editor or another process, permissions are insufficient, or a file is read-only on Windows.","commonSituations":"Re-running a ReplaceDirectory over a target that the editor or antivirus currently holds open. Replacing a directory containing read-only/version-controlled files. Replacing Library subfolders while assets are imported.","solutions":["Ensure nothing is holding files in dst open (close the editor, exclude the path from AV).","Clear read-only attributes on dst contents before replacing.","Catch IOException, log which path failed, and surface the OS error rather than retrying blindly.","If the destination must be replaced idempotently, delete with retries/back-off before calling ReplaceDirectory."],"exampleFix":"// before\nFileUtil.ReplaceDirectory(src, dst);\n// after\ntry { FileUtil.ReplaceDirectory(src, dst); }\ncatch (System.IO.IOException ex) { Debug.LogError($\"could not replace {dst}: {ex.Message}\"); throw; }","handlingStrategy":"try-catch","validationCode":"// Pre-clear read-only flags and ensure nothing holds dst open.\nforeach (var f in Directory.GetFiles(dst, \"*\", SearchOption.AllDirectories))\n    File.SetAttributes(f, FileAttributes.Normal);\nFileUtil.ReplaceDirectory(src, dst);","typeGuard":null,"tryCatchPattern":"try { FileUtil.ReplaceDirectory(src, dst); }\ncatch (System.IO.IOException ex)\n{ Debug.LogError($\"replace failed for {dst}: {ex.Message}\"); throw; }","preventionTips":["Close the editor and other processes before replacing a directory they may hold.","Clear read-only attributes on destination contents before replacing.","Exclude hot paths from antivirus scanning to avoid transient locks.","Log which directory failed so partial-replace risk is visible."],"tags":["filesystem","directory","replace","ioexception","delete-failure","unity-editor"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}