{"record":{"id":"f685e224e9287dcb","repo":"dgraph-io/badger","slug":"keys-not-in-sorted-order-last-key-s-key-s","errorCode":null,"errorMessage":"keys not in sorted order (last key: %s, key: %s)","messagePattern":"keys not in sorted order \\(last key: (.+?), key: (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"stream_writer.go","lineNumber":419,"sourceCode":"\n\tfor {\n\t\tselect {\n\t\tcase req := <-w.reqCh:\n\t\t\tprocess(req)\n\t\tcase <-w.closer.HasBeenClosed():\n\t\t\tclose(w.reqCh)\n\t\t\tfor req := range w.reqCh {\n\t\t\t\tprocess(req)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// Add adds key and vs to sortedWriter.\nfunc (w *sortedWriter) Add(key []byte, vs y.ValueStruct) error {\n\tif len(w.lastKey) > 0 && y.CompareKeys(key, w.lastKey) <= 0 {\n\t\treturn fmt.Errorf(\"keys not in sorted order (last key: %s, key: %s)\",\n\t\t\thex.Dump(w.lastKey), hex.Dump(key))\n\t}\n\n\tsameKey := y.SameKey(key, w.lastKey)\n\n\t// Same keys should go into the same SSTable.\n\tif !sameKey && w.builder.ReachedCapacity() {\n\t\tif err := w.send(false); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tw.lastKey = y.SafeCopy(w.lastKey, key)\n\tvar vp valuePointer\n\tif vs.Meta&bitValuePointer > 0 {\n\t\tvp.Decode(vs.Value)\n\t}\n","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/stream_writer.go#L401-L437","documentation":"sortedWriter.Add enforces that keys arrive in strictly ascending order, since SSTables must be built with sorted keys. If the incoming key is <= the last key added (by badger's internal key comparison, which includes version/timestamp), Add refuses to proceed.","triggerScenarios":"Adding keys to a StreamWriter/sortedWriter out of order — e.g. key <= previous key including same key with lower or equal version; feeding keys not sorted by the (key, version) tuple; using a key iteration order that doesn't match badger's CompareKeys semantics.","commonSituations":"Streaming from a source that isn't sorted (map iteration, unsorted database dump); re-adding the same key/version twice; loading data from an external store where the caller assumed plain lexicographic sort was enough but versions differ.","solutions":["Sort all entries by key and then by version descending (badger's internal order) before adding","Ensure each key+version pair is added at most once","If duplicate keys with different versions are expected, verify versions decrease for the same key as badger expects","Check the source iteration (e.g. db.NewKeyIterator) uses badger's ordering, not a custom comparator"],"exampleFix":"// before\nsort.Slice(entries, func(i, j int) bool { return bytes.Compare(entries[i].Key, entries[j].Key) < 0 })\n// after\nsort.Slice(entries, func(i, j int) bool {\n    if c := bytes.Compare(entries[i].Key, entries[j].Key); c != 0 { return c < 0 }\n    return entries[i].Version > entries[j].Version // badger requires descending versions\n})","handlingStrategy":"validation","validationCode":"// Go: validate ordering before Add\nvar lastKey []byte\nfunc checkOrdered(k []byte, v y.ValueStruct) error {\n    if len(lastKey) > 0 && badger y.CompareKeys(k, lastKey) <= 0 {\n        return fmt.Errorf(\"out of order: %s after %s\", k, lastKey)\n    }\n    lastKey = append(lastKey[:0], k...)\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Go\nif err := sw.Add(key, vs); err != nil {\n    if strings.Contains(err.Error(), \"keys not in sorted order\") {\n        return fmt.Errorf(\"input data unsorted at key %q: %w\", key, err)\n    }\n    return err\n}","preventionTips":["Sort by (key asc, version desc) before adding","Deduplicate key+version pairs before insertion","Use badger's CompareKeys, not plain bytes.Compare, when versions matter","Test your dump/export pipeline ordering on a sample first"],"tags":["sorted-order","sstable","data-loading"],"backgroundTag":"keys-not-sorted","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}