{"record":{"id":"b951316c53303a44","repo":"AdguardTeam/AdGuardHome","slug":"closing-w","errorCode":null,"errorMessage":"closing: %w","messagePattern":"closing: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/aghrenameio/renameio_windows.go","lineNumber":38,"sourceCode":"\n// type check\nvar _ PendingFile = (*pendingFile)(nil)\n\n// Cleanup implements the [PendingFile] interface for *pendingFile.\nfunc (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.","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghrenameio/renameio_windows.go#L20-L56","documentation":"On Windows, PendingFile.CloseReplace closes the temp file before renaming it over the target; this error means the underlying file.Close() itself failed. On Windows this commonly happens when another process holds the file open (sharing violation).","triggerScenarios":"Calling CloseReplace on a pending file whose handle can't be closed — an antivirus scanner, indexer, or other process has the temp file open in an incompatible mode; or the file handle was already invalidated.","commonSituations":"Windows Defender or search indexer briefly locking newly created temp files; a crashed previous run leaving handles; concurrent writers using the same pending-file name pattern.","solutions":["Retry the operation after a short delay — AV locks are usually transient","Add the data directory to antivirus exclusions for the writing process","Ensure only one process performs atomic writes to the same target path"],"exampleFix":"// retry pattern\nerr := pf.CloseReplace()\nif err != nil && strings.Contains(err.Error(), \"closing:\") {\n    time.Sleep(100 * time.Millisecond)\n    // reopen and rewrite, then CloseReplace again\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := pf.CloseReplace()\nif err != nil {\n    if strings.Contains(err.Error(), \"closing:\") {\n        time.Sleep(200 * time.Millisecond)\n        // rewrite via new PendingFile and retry once\n    }\n}","preventionTips":["Exclude working dirs from real-time AV scanning","Serialize writes to a target file from a single process","Retry once on Windows — handle locks are often transient"],"tags":["windows","file-close","sharing-violation","atomic-write"],"backgroundTag":"windows-file-close-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}