{"record":{"id":"ed5e2a4cdba50dd7","repo":"benbjohnson/litestream","slug":"rename-ltx-file-w","errorCode":null,"errorMessage":"rename ltx file: %w","messagePattern":"rename ltx file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":2237,"sourceCode":"\t}\n\tif err := ltxFile.Close(); err != nil {\n\t\tif isDiskFullError(err) {\n\t\t\treturn result, NewLTXError(\"stage-close\", tmpFilename, 0, uint64(txID), uint64(txID), fmt.Errorf(\"%w: %w\", ErrDiskFull, err))\n\t\t}\n\t\treturn result, fmt.Errorf(\"close ltx file: %w\", err)\n\t}\n\n\t// Atomically rename file to final path.\n\tdb.setSyncDiagPhase(diagPhaseRenameLTX, func(s *diagState) {\n\t\ts.txID = txID\n\t\ts.walSize = sz\n\t})\n\tif err := os.Rename(tmpFilename, filename); err != nil {\n\t\tdb.maxLTXFileInfos.Lock()\n\t\tdelete(db.maxLTXFileInfos.m, 0) // clear cache if in unknown state\n\t\tdb.maxLTXFileInfos.Unlock()\n\t\tdb.invalidatePosCache()\n\t\treturn result, fmt.Errorf(\"rename ltx file: %w\", err)\n\t}\n\tif err := internal.FsyncDir(filepath.Dir(filename)); err != nil {\n\t\tdb.maxLTXFileInfos.Lock()\n\t\tdelete(db.maxLTXFileInfos.m, 0) // clear cache if in unknown state\n\t\tdb.maxLTXFileInfos.Unlock()\n\t\tdb.invalidatePosCache()\n\t\treturn result, fmt.Errorf(\"sync ltx dir: %w\", err)\n\t}\n\n\tresult.synced = true\n\tresult.l0FileInfo = &ltx.FileInfo{\n\t\tLevel:     0,\n\t\tMinTXID:   txID,\n\t\tMaxTXID:   txID,\n\t\tCreatedAt: time.Now(),\n\t\tSize:      enc.N(),\n\t}\n","sourceCodeStart":2219,"sourceCodeEnd":2255,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L2219-L2255","documentation":"The completed temporary LTX file could not be atomically renamed to its final path. Litestream wraps the rename error with 'rename ltx file:' and, because the file may or may not exist in its final location, it clears the max-LTX-file-info cache and invalidates the position cache to avoid stale assumptions.","triggerScenarios":"os.Rename(tmpFilename, filename) at db.go:2232 failed: destination directory missing, permission denied, cross-device link (EXDEV) if temp and final paths are on different mounts, or the target is locked by another process.","commonSituations":"LTX path and temp path on different filesystems after repartitioning or mount changes; the LTX directory deleted by cleanup racing with a sync; permission changes on the data directory; read-only remounts.","solutions":["Ensure the LTX destination directory exists and is writable by the litestream user.","Verify temp file and final LTX path are on the same filesystem/mount to avoid EXDEV.","Check for cleanup/compaction processes deleting the target directory concurrently.","After fixing, run `litestream reset` if the position cache is suspected stale, then retry."],"exampleFix":"// before\n// config with mismatched paths\npath: /mnt/other-fs/db        # temp on different mount\n// after\npath: /var/lib/db             # same filesystem as temp dir\n# or ensure both under the same mount point","handlingStrategy":"try-catch","validationCode":"const st = fs.statSync(ltxDir)\nif (!st.isDirectory() || (st.mode & 0o200) === 0) throw new Error('LTX dir missing or not writable')","typeGuard":"func sameFilesystem(a, b string) bool {\n\tda, db := devOf(a), devOf(b)\n\treturn da == db // avoid EXDEV on rename\n}","tryCatchPattern":"if err := db.Sync(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"rename ltx file\") {\n\t\t// check dir existence/permissions and mount layout\n\t}\n\treturn err\n}","preventionTips":["Keep temp and final LTX paths on the same filesystem.","Ensure the data directory exists and is writable before startup.","Don't run retention/cleanup jobs that race with active syncs.","Use `litestream reset` after suspected stale position state."],"tags":["rename","atomic-write","filesystem"],"backgroundTag":"file-write-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}