{"record":{"id":"437f5997c9c0e0e8","repo":"weaviate/weaviate","slug":"prepend-segments-copy-files-w","errorCode":null,"errorMessage":"prepend segments: copy files: %w","messagePattern":"prepend segments: copy files: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"adapters/repos/db/lsmkv/segment_group_prepend.go","lineNumber":116,"sourceCode":"\t}\n\tdefer func() {\n\t\t// Best-effort resume — if this fails, the segment group's compaction\n\t\t// stays paused, which is degraded but not data-losing.\n\t\t_ = sg.resumeCompaction(ctx)\n\t}()\n\n\t// Step 3: Compute timestamp shift and copy files with crash-safe staging.\n\ttgtDBFiles, err := discoverDBFiles(sg.dir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"prepend segments: discover target segments: %w\", err)\n\t}\n\tshift, err := computeTimestampShift(srcDBFiles, tgtDBFiles)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"prepend segments: compute timestamp shift: %w\", err)\n\t}\n\tcopiedDBPaths, err := copySegmentFiles(srcDir, sg.dir, srcDBFiles, shift)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"prepend segments: copy files: %w\", err)\n\t}\n\n\t// Step 4: Initialize segments from the copied .db files.\n\tinitialized, err := sg.initPrependedSegments(copiedDBPaths)\n\tif err != nil {\n\t\t// Clean up copied files on failure.\n\t\tcleanupCopiedFiles(sg.dir, copiedDBPaths)\n\t\treturn fmt.Errorf(\"prepend segments: init segments: %w\", err)\n\t}\n\n\t// Step 5: Atomic prepend under maintenanceLock.\n\tfunc() {\n\t\tsg.maintenanceLock.Lock()\n\t\tdefer sg.maintenanceLock.Unlock()\n\n\t\tnewSegments := make([]Segment, 0, len(initialized)+len(sg.segments))\n\t\tnewSegments = append(newSegments, initialized...)\n\t\tnewSegments = append(newSegments, sg.segments...)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/repos/db/lsmkv/segment_group_prepend.go#L98-L134","documentation":"copySegmentFiles failed while copying segment files from srcDir into the target directory with the timestamp shift applied. The wrapped cause can be an error finding associated files (index 2149), parsing the timestamp, opening/creating files, copying, fsyncing, or renaming the staged .tmp files. Copied state is cleaned up so no partial segments remain staged without .tmp handling.","triggerScenarios":"Disk full on the target volume so copyFileWithSync's os.Create or io.Copy fails; source file removed between discovery and copy (source bucket not shut down / still compacting); rename(2) failing across filesystems or due to permissions.","commonSituations":"Restoring a backup onto a volume with insufficient free space; running the restore while the source bucket is live (violating the documented precondition that the source must be shut down and immutable); EACCES/EPERM from restrictive file modes.","solutions":["Ensure the source bucket is shut down and immutable before calling PrependSegmentsFromBucket (the documented precondition)","Free disk space on the target volume or restore to a volume with room for the full segment set","Re-run after fixing permissions; failed copies are cleaned up so the operation is safely retryable"],"exampleFix":"// before\ngo bucket.Close()\nerr := sg.PrependSegmentsFromBucket(ctx, srcDir) // src mutated mid-copy if not closed\n// after\nsrcBucket.Shutdown(ctx) // guarantee source immutability\nerr = sg.PrependSegmentsFromBucket(ctx, srcDir)","handlingStrategy":"try-catch","validationCode":"// check free space and source immutability up front\nvar st syscall.Statfs_t\nsyscall.Statfs(dstDir, &st)\nif uint64(st.Bavail)*uint64(st.Bsize) < requiredBytes {\n    return errors.New(\"insufficient disk space for prepend\")\n}","typeGuard":null,"tryCatchPattern":"if err := sg.PrependSegmentsFromBucket(ctx, srcDir); err != nil {\n    // copies are cleaned up; safe to retry after fixing cause\n    if strings.Contains(err.Error(), \"copy \") || strings.Contains(err.Error(), \"rename \") {\n        return retryWithBackoff(ctx, func() error {\n            return sg.PrependSegmentsFromBucket(ctx, srcDir)\n        })\n    }\n    return err\n}","preventionTips":["Shut down the source bucket before prepending (documented precondition)","Provision disk space at least equal to the source segment set size","Retry prepends after transient IO errors; staging/cleanup makes them idempotent"],"tags":["lsmkv","go","filesystem","io","disk"],"backgroundTag":"segment-copy-failed","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}