JosefNemec/Playnite · error · IOException
Failed to write to {path}
Error message
Failed to write to {path} What it means
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.
Source
Thrown at source/Playnite/Common/FileSystem.cs:291
path = Paths.FixPathLength(path);
IOException ioException = null;
for (int i = 0; i < retryAttempts; i++)
{
try
{
PrepareSaveFile(path);
File.WriteAllText(path, content);
return;
}
catch (IOException exc)
{
logger.Debug($"Can't write to a file, trying again. {path}");
ioException = exc;
Task.Delay(500).Wait();
}
}
throw new IOException($"Failed to write to {path}", ioException);
}
public static void DeleteFileSafe(string path, int retryAttempts = 5)
{
if (!File.Exists(path))
{
return;
}
IOException ioException = null;
for (int i = 0; i < retryAttempts; i++)
{
try
{
File.Delete(path);
return;
}
catch (IOException exc)
View on GitHub (pinned to 5911f4e964)
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.
Example fix
// before FileSystem.WriteStringToFileSafe(path, json); // after — verify target dir + free space, then write atomically via temp var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); var tmp = path + ".tmp"; FileSystem.WriteStringToFileSafe(tmp, json); File.Delete(path); File.Move(tmp, path);
Defensive patterns
Strategy: retry
Validate before calling
var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); var fi = new FileInfo(path); if (fi.Exists && fi.IsReadOnly) fi.IsReadOnly = false;
Try / catch
try { FileSystem.WriteStringToFileSafe(path, json, 10); }
catch (IOException ex) { logger.Error(ex.InnerException ?? ex, $"write failed {path}"); /* temp-file + move fallback */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to delete {path}
- Failed to read {path}
- Cannot add file to database, file not found.
- Source directory does not exist or could not be found: {sour
- Root directory is not set or does not exist.
AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13).
Data as JSON: /api/errors/d30ba03b8467eb42.
Report an issue: GitHub.