{"record":{"id":"e98b4d5dbb4ea4c9","repo":"JosefNemec/Playnite","slug":"failed-to-delete-path","errorCode":null,"errorMessage":"Failed to delete {path}","messagePattern":"Failed to delete (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"warning","filePath":"source/Playnite/Common/FileSystem.cs","lineNumber":322,"sourceCode":"                try\r\n                {\r\n                    File.Delete(path);\r\n                    return;\r\n                }\r\n                catch (IOException exc)\r\n                {\r\n                    logger.Debug($\"Can't detele file, trying again. {path}\");\r\n                    ioException = exc;\r\n                    Task.Delay(500).Wait();\r\n                }\r\n                catch (UnauthorizedAccessException exc)\r\n                {\r\n                    logger.Error(exc, $\"Can't detele file, UnauthorizedAccessException. {path}\");\r\n                    return;\r\n                }\r\n            }\r\n\r\n            throw new IOException($\"Failed to delete {path}\", ioException);\r\n        }\r\n\r\n        public static long GetFreeSpace(string drivePath)\r\n        {\r\n            var root = Path.GetPathRoot(drivePath);\r\n            var drive = DriveInfo.GetDrives().FirstOrDefault(a => a.RootDirectory.FullName.Equals(root, StringComparison.OrdinalIgnoreCase)); ;\r\n            if (drive != null)\r\n            {\r\n                return drive.AvailableFreeSpace;\r\n            }\r\n            else\r\n            {\r\n                return 0;\r\n            }\r\n        }\r\n\r\n        public static long GetFileSize(string path)\r\n        {\r","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Playnite/Common/FileSystem.cs#L304-L340","documentation":"Thrown by FileSystem.DeleteFileSafe after retryAttempts (default 5) consecutive IOExceptions from File.Delete, each retry sleeping 500ms. IMPORTANT: UnauthorizedAccessException is caught separately and returns SILENTLY (no throw), so this exception only fires for IOException-class failures; the inner IOException holds the real reason.","triggerScenarios":"File.Delete raising IOException for the full retry window because another process holds the file open; AV scanning the file during delete; pending delete blocked by an open handle.","commonSituations":"Cleaning up temp/cover/cache files still referenced by an image control or scanner; deleting a file on a slow network share; file enqueued for delete by Windows but not yet removed.","solutions":["Close/release handles (image streams, indexes) that reference the file before deleting.","Re-check with File.Exists after the call — a pending delete may succeed later.","Inspect ex.InnerException for the underlying Win32 error.","If a permission failure is expected, know that UnauthorizedAccessException returns silently here — check existence afterward to confirm.","Exclude the folder from AV to remove scan-window locks."],"exampleFix":"// before\nFileSystem.DeleteFileSafe(path);\n\n// after — release handles, then best-effort delete with existence check\nimgSource = null; // release any image handle\nFileSystem.DeleteFileSafe(path);\nif (File.Exists(path)) logger.Warn($\"Delete pending or blocked: {path}\");","handlingStrategy":"try-catch","validationCode":"if (!File.Exists(path)) return; // nothing to do","typeGuard":null,"tryCatchPattern":"try { FileSystem.DeleteFileSafe(path); }\ncatch (IOException ex) { logger.Warn(ex.InnerException ?? ex, $\"delete blocked {path}\"); }\n// NOTE: UnauthorizedAccessException is swallowed internally; verify with File.Exists","preventionTips":["Release image/handle references to the file before deleting.","Remember UnauthorizedAccessException returns silently here — verify deletion with File.Exists.","Re-check existence shortly after for pending-delete files."],"tags":["filesystem","io","file-locking","retry","playnite"],"backgroundTag":null,"analyzedSha":"5911f4e964e628aa7a69c2030ab35101afa63067","analyzedAt":"2026-08-13T17:38:25.713Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}