{"record":{"id":"50e8ac5834fb12be","repo":"dgraph-io/badger","slug":"cannot-use-newmanagedwritebatch-with-manageddb-fal","errorCode":null,"errorMessage":"cannot use NewManagedWriteBatch with managedDB=false. Use NewWriteBatch instead","messagePattern":"cannot use NewManagedWriteBatch with managedDB=false\\. Use NewWriteBatch instead","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"managed_db.go","lineNumber":46,"sourceCode":"\ttxn.readTs = readTs\n\treturn txn\n}\n\n// NewWriteBatchAt is similar to NewWriteBatch but it allows user to set the commit timestamp.\n// NewWriteBatchAt is supposed to be used only in the managed mode.\nfunc (db *DB) NewWriteBatchAt(commitTs uint64) *WriteBatch {\n\tif !db.opt.managedTxns {\n\t\tpanic(\"cannot use NewWriteBatchAt with managedDB=false. Use NewWriteBatch instead\")\n\t}\n\n\twb := db.newWriteBatch(true)\n\twb.commitTs = commitTs\n\twb.txn.commitTs = commitTs\n\treturn wb\n}\nfunc (db *DB) NewManagedWriteBatch() *WriteBatch {\n\tif !db.opt.managedTxns {\n\t\tpanic(\"cannot use NewManagedWriteBatch with managedDB=false. Use NewWriteBatch instead\")\n\t}\n\n\twb := db.newWriteBatch(true)\n\treturn wb\n}\n\n// CommitAt commits the transaction, following the same logic as Commit(), but\n// at the given commit timestamp. This will panic if not used with managed transactions.\n//\n// This is only useful for databases built on top of Badger (like Dgraph), and\n// can be ignored by most users.\nfunc (txn *Txn) CommitAt(commitTs uint64, callback func(error)) error {\n\tif !txn.db.opt.managedTxns {\n\t\tpanic(\"Cannot use CommitAt with managedDB=false. Use Commit instead.\")\n\t}\n\ttxn.commitTs = commitTs\n\tif callback == nil {\n\t\treturn txn.Commit()","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/managed_db.go#L28-L64","documentation":"DB.NewManagedWriteBatch returns a WriteBatch that assumes managed-mode transaction semantics (caller-controlled commit timestamps / conflict detection bypass). When the DB was opened without managed transactions the library panics, telling you to use NewWriteBatch instead. Like the other managed_db.go guards, this is deliberate API-misuse detection rather than a recoverable error.","triggerScenarios":"Calling db.NewManagedWriteBatch() on a DB opened without WithManagedTxns(true). Seen in caller writeRandom, where benchmark/loader code assumed a managed DB. Panic raised at managed_db.go:46 before any batch is allocated.","commonSituations":"Running Badger benchmark or loader tools (e.g. writeRandom) against a DB opened with default options; refactoring code from a Dgraph-style managed setup to a standalone DB; enabling batch writes for performance without enabling managed mode.","solutions":["Open the DB with WithManagedTxns(true): badger.DefaultOptions(dir).WithManagedTxns(true).","If you do not need managed semantics, switch the call to db.NewWriteBatch().","Fix the caller (e.g. writeRandom) so its DB-opening path matches the batch API it uses.","Guard the write path: check that managed mode is on before choosing the At/Managed batch constructors."],"exampleFix":"// before\nopts := badger.DefaultOptions(dir)\ndb, _ := badger.Open(opts)\nwb := db.NewManagedWriteBatch()\n// after\nopts := badger.DefaultOptions(dir).WithManagedTxns(true)\ndb, _ := badger.Open(opts)\nwb := db.NewManagedWriteBatch()\n// ...or, without managed mode:\nwb := db.NewWriteBatch()","handlingStrategy":"validation","validationCode":"if !managedMode {\n    wb = db.NewWriteBatch()\n} else {\n    wb = db.NewManagedWriteBatch()\n}","typeGuard":"func supportsManagedWriteBatch(managedTxns bool) bool { return managedTxns }","tryCatchPattern":"func safeNewManagedWriteBatch(db *badger.DB) (wb *badger.WriteBatch, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"NewManagedWriteBatch requires managed mode: %v\", r)\n        }\n    }()\n    wb = db.NewManagedWriteBatch()\n    return\n}","preventionTips":["Fix tools like writeRandom to open the DB with WithManagedTxns(true) when they use NewManagedWriteBatch","Prefer db.NewWriteBatch() for normal bulk loads — it needs no managed mode","Keep one DB-open function per binary so batch API choice and open options cannot drift","Add a unit test that opens the DB in both modes and asserts which batch constructors succeed"],"tags":["go","badger","managed-transactions","write-batch","panic"],"backgroundTag":"managed-mode-required","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"}