{"record":{"id":"66b7f024465dbf8c","repo":"weaviate/weaviate","slug":"merge-keys-w","errorCode":null,"errorMessage":"merge keys: %w","messagePattern":"merge keys: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"adapters/repos/db/lsmkv/compactor_inverted.go","lineNumber":328,"sourceCode":"\t\treturn 0, err\n\t}\n\tc.offset += len(encoded) + 8 + 8 + 8\n\treturn len(encoded) + 8 + 8 + 8, nil\n}\n\nfunc (c *compactorInverted) writeKeys(ctx context.Context) ([]segmentindex.KeyRedux, error) {\n\tkey1, value1, _ := c.c1.first()\n\tkey2, value2, _ := c.c2.first()\n\n\t// the (dummy) header was already written, this is our initial offset\n\n\tkis := make([]segmentindex.KeyRedux, 0, c.c1.segment.index.KeyCount()+c.c2.segment.index.KeyCount())\n\tsim := newSortedMapMerger()\n\n\tfor i := 0; ; i++ {\n\t\tif i%compactor.AbortCheckEveryN == 0 {\n\t\t\tif err := ctx.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"merge keys: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\tif key1 == nil && key2 == nil {\n\t\t\tbreak\n\t\t}\n\t\tif bytes.Equal(key1, key2) {\n\n\t\t\tvalue1Clean, _ := c.cleanupValues(value1)\n\n\t\t\tsim.reset([][]MapPair{value1Clean, value2})\n\t\t\tmergedPairs, err := sim.\n\t\t\t\tdoKeepTombstonesReusable()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif len(mergedPairs) == 0 {","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/repos/db/lsmkv/compactor_inverted.go#L310-L346","documentation":"While merging keys of two inverted-index segments, writeKeys periodically checks ctx.Err() (every AbortCheckEveryN iterations) so a cancelled or timed-out context stops the merge promptly. On cancellation it returns \"merge keys: %w\" wrapping context.Canceled or context.DeadlineExceeded. This is a cooperative-abort mechanism, not data corruption.","triggerScenarios":"The context passed into the compaction/merge is cancelled or its deadline expires while writeKeys is iterating merged keys — e.g. shutdown, shard drop, or an upper-layer timeout on a long merge of large segments.","commonSituations":"Server shutdown or shard release during a large compaction; overly tight timeouts on background operations; very large inverted segments making merges exceed deadlines.","solutions":["Expected on graceful shutdown — no action needed; compaction resumes later","If unintended, increase the timeout governing the compaction context","Reduce merge sizes / tune compaction schedule to avoid long-running merges","Ensure the context isn't cancelled prematurely by the caller (e.g. request-scoped ctx used for background work)"],"exampleFix":"// before: request-scoped context used for background compaction\ncompactor.Do(ctx) // ctx dies with the HTTP request\n// after\ncctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)\ndefer cancel()\ncompactor.Do(cctx)","handlingStrategy":"retry","validationCode":"// verify the context outlives the merge before starting\nif ctx.Err() != nil {\n    return fmt.Errorf(\"context already done before merge: %w\", ctx.Err())\n}\ndeadline, ok := ctx.Deadline()\nif ok && time.Until(deadline) < estimatedMergeTime {\n    // extend deadline or use a background context\n}","typeGuard":null,"tryCatchPattern":"if err := compactor.Do(ctx); err != nil {\n    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n        // benign on shutdown; otherwise retry with a longer-lived context\n        return retryWithBackgroundContext(job)\n    }\n    return err\n}","preventionTips":["Use background (not request-scoped) contexts for compaction jobs","Set generous deadlines proportional to segment sizes","Avoid cancelling contexts during shutdown until merges can checkpoint","Schedule compactions outside peak load to reduce timeout risk"],"tags":["go","lsmkv","compaction","context-cancellation"],"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"}