{"record":{"id":"a7afcd2b0d26d2f6","repo":"weaviate/weaviate","slug":"prepend-segments-pause-compaction-w","errorCode":null,"errorMessage":"prepend segments: pause compaction: %w","messagePattern":"prepend segments: pause compaction: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"adapters/repos/db/lsmkv/segment_group_prepend.go","lineNumber":97,"sourceCode":"\t\treturn fmt.Errorf(\"%w (bucket=%s)\", ErrPrependWouldDesyncInMemoryRep, filepath.Base(sg.dir))\n\t}\n\n\t// Step 2: Discover source segments (.db files).\n\tsrcDBFiles, err := discoverDBFiles(srcDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"prepend segments: discover source segments: %w\", err)\n\t}\n\tif len(srcDBFiles) == 0 {\n\t\treturn nil // no-op\n\t}\n\n\t// Pause compaction for the duration of the operation. Compaction's\n\t// switchInMemory uses stored segment indices — a prepend that shifts\n\t// indices while compaction is in flight would cause it to replace the\n\t// wrong segment. Pausing ensures no compaction cycle starts (and waits\n\t// for any in-progress cycle to finish) before we proceed.\n\tif err := sg.pauseCompaction(ctx); err != nil {\n\t\treturn fmt.Errorf(\"prepend segments: pause compaction: %w\", err)\n\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 {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/repos/db/lsmkv/segment_group_prepend.go#L79-L115","documentation":"pauseCompaction failed while preparing the segment group for prepending, so the operation aborts to avoid racing a compaction cycle that could replace the wrong segment when indices shift. The underlying error (typically context cancellation) is wrapped with 'prepend segments: pause compaction:'.","triggerScenarios":"The ctx passed to PrependSegmentsFromBucket is cancelled or times out while pauseCompaction waits for an in-progress compaction cycle to finish; the segment group's pause mechanism itself errors.","commonSituations":"Restore invoked with a request-scoped context that gets cancelled; long-running compaction on a large shard exceeding the caller's timeout; server shutdown mid-restore.","solutions":["Pass a context without a short deadline (context.Background() or a generous timeout) when calling PrependSegmentsFromBucket","Retry the operation after the in-flight compaction completes","Investigate why pauseCompaction failed (check logs for the wrapped cause) and ensure no shutdown is racing the restore"],"exampleFix":"// before\nerr := sg.PrependSegmentsFromBucket(ctx, srcDir) // request ctx, cancels quickly\n// after\nerr = sg.PrependSegmentsFromBucket(context.Background(), srcDir)","handlingStrategy":"retry","validationCode":"// avoid passing short-lived request contexts\ncctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)\ndefer cancel()\nerr := sg.PrependSegmentsFromBucket(cctx, srcDir)","typeGuard":null,"tryCatchPattern":"err := sg.PrependSegmentsFromBucket(ctx, srcDir)\nif errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n    return retryWithBackoff(ctx, func() error {\n        return sg.PrependSegmentsFromBucket(context.Background(), srcDir)\n    })\n}","preventionTips":["Use context.Background() (or a long timeout) for maintenance operations like prepend","Avoid running prepend during server shutdown when pauseCompaction may be interrupted","Monitor compaction backlog so pauseCompaction doesn't wait excessively"],"tags":["lsmkv","go","context","compaction"],"backgroundTag":"context-canceled","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"}