{"record":{"id":"6a2ae210e2306db9","repo":"dgraph-io/badger","slug":"this-api-can-not-be-called-in-managed-mode","errorCode":null,"errorMessage":"This API can not be called in managed mode.","messagePattern":"This API can not be called in managed mode\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"stream.go","lineNumber":491,"sourceCode":"\n\t// Wait for key streaming to be over.\n\terr := <-kvErr\n\treturn err\n}\n\nfunc (db *DB) newStream() *Stream {\n\treturn &Stream{\n\t\tdb:        db,\n\t\tNumGo:     db.opt.NumGoroutines,\n\t\tLogPrefix: \"Badger.Stream\",\n\t\tMaxSize:   maxStreamSize,\n\t}\n}\n\n// NewStream creates a new Stream.\nfunc (db *DB) NewStream() *Stream {\n\tif db.opt.managedTxns {\n\t\tpanic(\"This API can not be called in managed mode.\")\n\t}\n\treturn db.newStream()\n}\n\n// NewStreamAt creates a new Stream at a particular timestamp. Should only be used with managed DB.\nfunc (db *DB) NewStreamAt(readTs uint64) *Stream {\n\tif !db.opt.managedTxns {\n\t\tpanic(\"This API can only be called in managed mode.\")\n\t}\n\tstream := db.newStream()\n\tstream.readTs = readTs\n\treturn stream\n}\n\nfunc BufferToKVList(buf *z.Buffer) (*pb.KVList, error) {\n\tvar list pb.KVList\n\terr := buf.SliceIterate(func(s []byte) error {\n\t\tkv := new(pb.KV)","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/stream.go#L473-L509","documentation":"NewStream panics when the DB was opened with managed transactions (managedTxns=true). In managed mode the stream API must be driven via explicit timestamps (NewStreamAt), so the unmanaged NewStream entry point is disallowed. The library enforces this invariant with a panic rather than an error return.","triggerScenarios":"Calling db.NewStream() on a DB opened with badger.Open followed by WithManagedTxns(true) (or via OpenManaged); typically reached indirectly through db.Backup() when the DB is in managed mode.","commonSituations":"Configuring managed mode for Subscribe/versioned workflows but reusing unmanaged-mode backup/iterate code; copy-pasting example code written for a normal DB into a managed DB app.","solutions":["Open the DB in normal (unmanaged) mode with badger.Open(opts) if you want db.NewStream()/Backup to work","If you must stay in managed mode, use db.NewStreamAt(readTs) with an explicit read timestamp instead of NewStream()","For Backup in managed mode, drive the stream yourself via NewStreamAt and db.WriteTo/BackupStream-equivalent flow with a chosen readTs"],"exampleFix":"// before\nbadgerDB, _ := badger.Open(badger.DefaultOptions(dir).WithManagedTxns(true))\n_, err := badgerDB.Backup(w, 0) // panics: NewStream in managed mode\n// after\nbadgerDB, _ := badger.OpenManaged(badger.DefaultOptions(dir))\nts := badgerDB.MaxVersion()\nstream := badgerDB.NewStreamAt(ts)\nstream.Send = func(buf *z.Buffer) error { return w.Write(buf.Bytes()) }\nif err := stream.Orchestrate(context.Background()); err != nil { /* ... */ }","handlingStrategy":"try-catch","validationCode":"func canUseNewStream(db *badger.DB) bool {\n    // Managed DBs reject NewStream; recover from the panic boundary instead.\n    return !isManaged(db)\n}","typeGuard":"func isManaged(db *badger.DB) bool {\n    defer func() { recover() }()\n    // Probe via API that behaves differently in managed mode, e.g.:\n    // db.MaxVersion() exists only meaningfully in managed mode; prefer\n    // tracking how you opened the DB in application state.\n    return db == nil\n}","tryCatchPattern":"func safeNewStream(db *badger.DB) (s *badger.Stream, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            if msg, ok := r.(string); ok && strings.Contains(msg, \"managed mode\") {\n                err = errors.New(\"db in managed mode: use NewStreamAt(readTs)\")\n                return\n            }\n            panic(r)\n        }\n    }()\n    s = db.NewStream()\n    return\n}","preventionTips":["Track whether the DB was opened with OpenManaged/Open(...WithManagedTxns(true)) in application config","Use NewStreamAt with db.MaxVersion() whenever the DB is managed","Keep separate code paths for managed and unmanaged DBs instead of sharing NewStream-based code"],"tags":["badger","panic","managed-mode","api-misuse"],"backgroundTag":"api-called-in-wrong-mode","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"}