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

  1. Inspect ex.InnerException for the concrete cause (disk-full vs sharing-violation vs unauthorized).
  2. Ensure the parent directory exists and the volume has free space (FileSystem.GetFreeSpace).
  3. Remove read-only/hidden/system attributes from the target before writing.
  4. Relieve the lock from the competing process or exclude the folder from AV/sync.
  5. 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

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


AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13). Data as JSON: /api/errors/d30ba03b8467eb42. Report an issue: GitHub.