{"record":{"id":"d30ba03b8467eb42","repo":"JosefNemec/Playnite","slug":"failed-to-write-to-path","errorCode":null,"errorMessage":"Failed to write to {path}","messagePattern":"Failed to write to (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"source/Playnite/Common/FileSystem.cs","lineNumber":291,"sourceCode":"            path = Paths.FixPathLength(path);\r\n            IOException ioException = null;\r\n            for (int i = 0; i < retryAttempts; i++)\r\n            {\r\n                try\r\n                {\r\n                    PrepareSaveFile(path);\r\n                    File.WriteAllText(path, content);\r\n                    return;\r\n                }\r\n                catch (IOException exc)\r\n                {\r\n                    logger.Debug($\"Can't write to a file, trying again. {path}\");\r\n                    ioException = exc;\r\n                    Task.Delay(500).Wait();\r\n                }\r\n            }\r\n\r\n            throw new IOException($\"Failed to write to {path}\", ioException);\r\n        }\r\n\r\n        public static void DeleteFileSafe(string path, int retryAttempts = 5)\r\n        {\r\n            if (!File.Exists(path))\r\n            {\r\n                return;\r\n            }\r\n\r\n            IOException ioException = null;\r\n            for (int i = 0; i < retryAttempts; i++)\r\n            {\r\n                try\r\n                {\r\n                    File.Delete(path);\r\n                    return;\r\n                }\r\n                catch (IOException exc)\r","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/JosefNemec/Playnite/blob/5911f4e964e628aa7a69c2030ab35101afa63067/source/Playnite/Common/FileSystem.cs#L273-L309","documentation":"Thrown by FileSystem.WriteStringToFileSafe after retryAttempts (default 5) consecutive IOExceptions while calling PrepareSaveFile + File.WriteAllText, each retry sleeping 500ms. The inner IOException carries the underlying write failure.","triggerScenarios":"Writing to a file that stays locked for the full retry window; target directory missing or read-only; disk full or quota exceeded during the write; path too long; file marked read-only or hidden+system; AV blocking the write.","commonSituations":"Persisting settings/metadata JSON while a background indexer or sync client holds the file; writing to a full USB stick; saving into a folder the user cannot write to after a permissions reset.","solutions":["Inspect ex.InnerException for the concrete cause (disk-full vs sharing-violation vs unauthorized).","Ensure the parent directory exists and the volume has free space (FileSystem.GetFreeSpace).","Remove read-only/hidden/system attributes from the target before writing.","Relieve the lock from the competing process or exclude the folder from AV/sync.","Raise retryAttempts for transient contention."],"exampleFix":"// before\nFileSystem.WriteStringToFileSafe(path, json);\n\n// after — verify target dir + free space, then write atomically via temp\nvar dir = Path.GetDirectoryName(path);\nif (!Directory.Exists(dir)) Directory.CreateDirectory(dir);\nvar tmp = path + \".tmp\";\nFileSystem.WriteStringToFileSafe(tmp, json);\nFile.Delete(path);\nFile.Move(tmp, path);","handlingStrategy":"retry","validationCode":"var dir = Path.GetDirectoryName(path);\nif (!Directory.Exists(dir)) Directory.CreateDirectory(dir);\nvar fi = new FileInfo(path);\nif (fi.Exists && fi.IsReadOnly) fi.IsReadOnly = false;","typeGuard":null,"tryCatchPattern":"try { FileSystem.WriteStringToFileSafe(path, json, 10); }\ncatch (IOException ex) { logger.Error(ex.InnerException ?? ex, $\"write failed {path}\"); /* temp-file + move fallback */ }","preventionTips":["Ensure the parent directory exists and the target file is not read-only.","Check free space before writing large payloads.","Write atomically via a temp file + File.Move to dodge lock contention."],"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"}