AutoDarkMode/Windows-Auto-Night-Mode · error · TimeoutException

Saving to {path} failed after 10 retries

Error message

Saving to {path} failed after 10 retries

What it means

Thrown by AdmConfigBuilder.SaveConfig after 10 failed retry attempts to write a YAML config file because the file remained locked (IsFileLocked returns true each iteration, sleeping 500ms between tries — up to ~5s total). The TimeoutException indicates a persistent file lock held by another process/handle that the 10-retry loop could not out-wait.

Source

Thrown at AutoDarkModeLib/AdmConfigBuilder.cs:158

        ISerializer yamlSerializer = yamlBuilder.Build();

        string yamlConfig = yamlSerializer.Serialize(obj);
        for (int i = 0; i < 10; i++)
        {
            if (IsFileLocked(new FileInfo(path)))
            {
                Thread.Sleep(500);
            }
            else
            {
                using StreamWriter writer = new(File.Open(path, FileMode.Create, FileAccess.Write));
                writer.WriteLine(yamlConfig);
                writer.Close();
                return;
            }
        }
        throw new TimeoutException($"Saving to {path} failed after 10 retries");
    }

    private string LoadFile(string path)
    {
        Loading = true;
        Exception readException = new TimeoutException($"Reading from {path} failed after 3 retries");
        for (int i = 0; i < 3; i++)
        {
            try
            {
                using StreamReader dataReader = new(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
                return dataReader.ReadToEnd();
            }
            catch (Exception ex)
            {
                readException = ex;
                Thread.Sleep(500);
            }

View on GitHub (pinned to c15b28e921)

Solutions

  1. Close any editor/preview that has the config YAML open, then retry the save.
  2. Exclude the %AppData%\AutoDarkMode folder from real-time AV/cloud-sync scanning.
  3. Ensure only one instance of the app+service is writing; serialize writes via the config-updated event.
  4. Increase retries / use a randomized backoff, or write to a temp file then atomic-rename so readers never see a partial file.
  5. Check for stale file handles from a crashed process (reboot if necessary).

Example fix

// before — 10x spin on IsFileLocked, writes non-atomically
for (int i = 0; i < 10; i++)
{
    if (IsFileLocked(new FileInfo(path))) { Thread.Sleep(500); continue; }
    using StreamWriter writer = new(File.Open(path, FileMode.Create, FileAccess.Write));
    writer.WriteLine(yamlConfig);
    return;
}
throw new TimeoutException(...);

// after — write temp + atomic replace, retry on IOException with backoff
string tmp = path + ".tmp";
for (int i = 0; i < 10; i++)
{
    try
    {
        File.WriteAllText(tmp, yamlConfig);
        if (File.Exists(path)) File.Replace(tmp, path, null);
        else File.Move(tmp, path);
        return;
    }
    catch (IOException) { Thread.Sleep(500); }
}
throw new TimeoutException($"Saving to {path} failed after 10 retries");
Defensive patterns

Strategy: retry

Validate before calling

// Check whether the config file is locked before attempting to save
public static bool IsConfigWritable(string path)
{
    if (!File.Exists(path)) return true;
    try { using var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None); return true; }
    catch (IOException) { return false; }
}

Try / catch

try
{
    builder.Save();
}
catch (TimeoutException ex)
{
    // file stayed locked through 10 retries — surface to user, offer config backup
    logger.LogError(ex, "Config save timed out");
    throw;
}

Prevention

When it happens

Trigger: SaveConfig(path, obj) loops 10 times; each iteration calls IsFileLocked(new FileInfo(path)) which tries to open the file with FileShare.None — if it throws IOException the file is considered locked. After 10 locked iterations, TimeoutException is thrown at line 158.

Common situations: Antivirus or backup software scanning the config file; another ADM process (svc + app) writing simultaneously; cloud-sync (OneDrive) holding a write lock; file on a network share with opportunistic locking; editor with the YAML file open; the writer itself previously crashed mid-write leaving a handle.

Related errors


AI-assisted analysis of AutoDarkMode/Windows-Auto-Night-Mode@c15b28e921 (2026-08-13). Data as JSON: /api/errors/fb47610a5bd27b22. Report an issue: GitHub.