dgraph-io/badger · error

cannot use NewManagedWriteBatch with managedDB=false. Use Ne

Error message

cannot use NewManagedWriteBatch with managedDB=false. Use NewWriteBatch instead

What it means

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.

Source

Thrown at managed_db.go:46

	txn.readTs = readTs
	return txn
}

// NewWriteBatchAt is similar to NewWriteBatch but it allows user to set the commit timestamp.
// NewWriteBatchAt is supposed to be used only in the managed mode.
func (db *DB) NewWriteBatchAt(commitTs uint64) *WriteBatch {
	if !db.opt.managedTxns {
		panic("cannot use NewWriteBatchAt with managedDB=false. Use NewWriteBatch instead")
	}

	wb := db.newWriteBatch(true)
	wb.commitTs = commitTs
	wb.txn.commitTs = commitTs
	return wb
}
func (db *DB) NewManagedWriteBatch() *WriteBatch {
	if !db.opt.managedTxns {
		panic("cannot use NewManagedWriteBatch with managedDB=false. Use NewWriteBatch instead")
	}

	wb := db.newWriteBatch(true)
	return wb
}

// CommitAt commits the transaction, following the same logic as Commit(), but
// at the given commit timestamp. This will panic if not used with managed transactions.
//
// This is only useful for databases built on top of Badger (like Dgraph), and
// can be ignored by most users.
func (txn *Txn) CommitAt(commitTs uint64, callback func(error)) error {
	if !txn.db.opt.managedTxns {
		panic("Cannot use CommitAt with managedDB=false. Use Commit instead.")
	}
	txn.commitTs = commitTs
	if callback == nil {
		return txn.Commit()

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Open the DB with WithManagedTxns(true): badger.DefaultOptions(dir).WithManagedTxns(true).
  2. If you do not need managed semantics, switch the call to db.NewWriteBatch().
  3. Fix the caller (e.g. writeRandom) so its DB-opening path matches the batch API it uses.
  4. Guard the write path: check that managed mode is on before choosing the At/Managed batch constructors.

Example fix

// before
opts := badger.DefaultOptions(dir)
db, _ := badger.Open(opts)
wb := db.NewManagedWriteBatch()
// after
opts := badger.DefaultOptions(dir).WithManagedTxns(true)
db, _ := badger.Open(opts)
wb := db.NewManagedWriteBatch()
// ...or, without managed mode:
wb := db.NewWriteBatch()
Defensive patterns

Strategy: validation

Validate before calling

if !managedMode {
    wb = db.NewWriteBatch()
} else {
    wb = db.NewManagedWriteBatch()
}

Type guard

func supportsManagedWriteBatch(managedTxns bool) bool { return managedTxns }

Try / catch

func safeNewManagedWriteBatch(db *badger.DB) (wb *badger.WriteBatch, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("NewManagedWriteBatch requires managed mode: %v", r)
        }
    }()
    wb = db.NewManagedWriteBatch()
    return
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05). Data as JSON: /api/errors/50e8ac5834fb12be. Report an issue: GitHub.