{"record":{"id":"cc396698abd120f9","repo":"AdguardTeam/AdGuardHome","slug":"renaming-w","errorCode":null,"errorMessage":"renaming: %w","messagePattern":"renaming: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghrenameio/renameio_windows.go","lineNumber":43,"sourceCode":"func (f *pendingFile) Cleanup() (err error) {\n\tcloseErr := f.file.Close()\n\terr = os.Remove(f.file.Name())\n\n\t// Put closeErr into the deferred error because that's where it is usually\n\t// expected.\n\treturn errors.WithDeferred(err, closeErr)\n}\n\n// CloseReplace implements the [PendingFile] interface for *pendingFile.\nfunc (f *pendingFile) CloseReplace() (err error) {\n\terr = f.file.Close()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"closing: %w\", err)\n\t}\n\n\terr = os.Rename(f.file.Name(), f.targetPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"renaming: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// Write implements the [PendingFile] interface for *pendingFile.\nfunc (f *pendingFile) Write(b []byte) (n int, err error) {\n\treturn f.file.Write(b)\n}\n\n// NewPendingFile is a wrapper around [os.CreateTemp].\n//\n// f.Close must be called to finish the renaming.\nfunc newPendingFile(filePath string, mode fs.FileMode) (f PendingFile, err error) {\n\t// Use the same directory as the file itself, because moves across\n\t// filesystems can be especially problematic.\n\tfile, err := os.CreateTemp(filepath.Dir(filePath), \"\")\n\tif err != nil {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghrenameio/renameio_windows.go#L25-L61","documentation":"On Windows, PendingFile.CloseReplace does an os.Rename of the temp file onto the target path; this error wraps a rename failure. Windows renames fail when the destination exists and is locked by another process, unlike POSIX rename semantics.","triggerScenarios":"Calling CloseReplace while the target file is open by another process (config reader, editor, AV); target file has read-only attributes; temp file and target on different volumes; target directory permissions insufficient.","commonSituations":"Atomic config-file replacement on Windows while the config is being read or watched; read-only files under version control; concurrent AdGuardHome instances writing the same config.","solutions":["Close/stop whatever holds the target file open (readers, watchers, editors) before replacing","Remove read-only attributes: attrib -r <file>","Retry with backoff — Windows rename locking is often transient (AV)","Ensure only one instance writes the target"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := pf.CloseReplace()\nif err != nil && strings.Contains(err.Error(), \"renaming:\") {\n    time.Sleep(200 * time.Millisecond)\n    err = pf.CloseReplace() // or recreate pending file and retry\n}","preventionTips":["Ensure no readers/watchers hold the target open during replacement","Clear read-only attributes on targets","On Windows expect rename-vs-open-file races; design for retry"],"tags":["windows","rename","file-locked","atomic-write"],"backgroundTag":"windows-rename-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}