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
- Close any editor/preview that has the config YAML open, then retry the save.
- Exclude the %AppData%\AutoDarkMode folder from real-time AV/cloud-sync scanning.
- Ensure only one instance of the app+service is writing; serialize writes via the config-updated event.
- Increase retries / use a randomized backoff, or write to a temp file then atomic-rename so readers never see a partial file.
- 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
- Write config via temp-file + atomic File.Replace so readers never block and partial files are impossible.
- Exclude %AppData%\AutoDarkMode from real-time AV and cloud-sync scanning.
- Serialize writes from app and service through the ConfigUpdated event to avoid concurrent Save() calls.
- Use jittered backoff instead of fixed 500ms sleeps to avoid lock-step contention.
- Keep the config on a local drive, not a network share with op-locking.
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.