{"record":{"id":"c6fcf88ca0643490","repo":"fatedier/frp","slug":"failed-to-rename-temp-file-w","errorCode":null,"errorMessage":"failed to rename temp file: %w","messagePattern":"failed to rename temp file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/config/source/store.go","lineNumber":174,"sourceCode":"\t\tf.Close()\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"failed to write temp file: %w\", err)\n\t}\n\n\tif err := f.Sync(); err != nil {\n\t\tf.Close()\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"failed to sync temp file: %w\", err)\n\t}\n\n\tif err := f.Close(); err != nil {\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"failed to close temp file: %w\", err)\n\t}\n\n\tif err := os.Rename(tmpPath, s.config.Path); err != nil {\n\t\tos.Remove(tmpPath)\n\t\treturn fmt.Errorf(\"failed to rename temp file: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *StoreSource) persistOrRollbackUnlocked(rollback func()) error {\n\tif err := s.saveToFileUnlocked(); err != nil {\n\t\trollback()\n\t\treturn fmt.Errorf(\"failed to persist: %w\", err)\n\t}\n\treturn nil\n}\n\n// Store map selectors return the target map for generic helpers.\nfunc proxyStoreEntries(s *StoreSource) map[string]v1.ProxyConfigurer {\n\treturn s.proxies\n}\n","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/config/source/store.go#L156-L192","documentation":"The final os.Rename(tmpPath, Path) failed, so the new store content never became live. Everything before (marshal, mkdir, write, fsync, close) succeeded; rename failures are typically locking or path-type issues rather than content issues. The temp file is removed on this path.","triggerScenarios":"On Windows, another process holds the destination open without FILE_SHARE_DELETE (antivirus scanners, editors tailing the file, backup software); the destination path exists as a DIRECTORY; EACCES on the containing directory; extremely rare EXDEV is impossible here because the temp file lives in the same directory.","commonSituations":"frpc on Windows with an AV scanning store.json at the wrong moment; a user watching the file in a tail/editor; a log-rotation/backup agent pinning it; destination accidentally replaced by a directory.","solutions":["Retry the operation — transient Windows share violations usually clear once the scanner/editor releases the file","Add a store-directory exclusion for the antivirus, or close the editor/tail holding the file","Verify nothing replaced the destination with a directory: ls -la <dir>","Check directory write permission (rename needs it even though the file itself is writable)"],"exampleFix":"# windows: exclude store dir from real-time AV scanning\nAdd-MpPreference -ExclusionPath 'C:\\frp\\store.json'\n\n# then retry the failed Add/Update/Remove operation","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := store.AddProxy(cfg)\nif err != nil && strings.Contains(err.Error(), \"failed to rename temp file\") {\n\t// common on Windows: AV/editor holding store.json. Safe to retry after a short delay;\n\t// rollback removed the temp file and reverted memory, so AddProxy is idempotent to re-run.\n\ttime.Sleep(200 * time.Millisecond)\n\terr = store.AddProxy(cfg)\n}","preventionTips":["On Windows, exclude the store directory from real-time antivirus scanning","Don't tail the store file with tools that hold it open without share-delete","Ensure the destination path is never replaced by a directory"],"tags":["filesystem","rename","windows","file-locking","atomic-write","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}